Menulis Aplikasi Responsif
Salah satu kunci untuk mempertahankan GUI responsif adalah melakukan tugas jangka panjang pada utas latar belakang sehingga GUI tidak diblokir. Katakanlah kita ingin menghitung nilai yang akan ditampilkan kepada pengguna, tetapi nilai tersebut membutuhkan waktu 5 detik untuk menghitung:
public class ThreadDemo : Activity
{
TextView textview;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create a new TextView and set it as our view
textview = new TextView (this);
textview.Text = "Working..";
SetContentView (textview);
SlowMethod ();
}
private void SlowMethod ()
{
Thread.Sleep (5000);
textview.Text = "Method Complete";
}
}
Ini akan berfungsi, tetapi aplikasi akan "macet" selama 5 detik saat nilai dihitung. Selama waktu ini, aplikasi tidak akan merespons interaksi pengguna apa pun. Untuk mengatasi hal ini, kita ingin melakukan perhitungan pada utas latar belakang:
public class ThreadDemo : Activity
{
TextView textview;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create a new TextView and set it as our view
textview = new TextView (this);
textview.Text = "Working..";
SetContentView (textview);
ThreadPool.QueueUserWorkItem (o => SlowMethod ());
}
private void SlowMethod ()
{
Thread.Sleep (5000);
textview.Text = "Method Complete";
}
}
Sekarang kita menghitung nilai pada utas latar belakang sehingga GUI kita tetap responsif selama perhitungan. Namun, ketika perhitungan selesai, aplikasi kami mengalami crash, meninggalkan ini di log:
E/mono (11207): EXCEPTION handling: Android.Util.AndroidRuntimeException: Exception of type 'Android.Util.AndroidRuntimeException' was thrown.
E/mono (11207):
E/mono (11207): Unhandled Exception: Android.Util.AndroidRuntimeException: Exception of type 'Android.Util.AndroidRuntimeException' was thrown.
E/mono (11207): at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms)
E/mono (11207): at Android.Widget.TextView.set_Text (IEnumerable`1 value)
E/mono (11207): at MonoDroidDebugging.Activity1.SlowMethod ()
Ini karena Anda harus memperbarui GUI dari utas GUI. Kode kami memperbarui GUI dari utas ThreadPool, menyebabkan aplikasi mengalami crash. Kita perlu menghitung nilai kita pada utas latar belakang, tetapi kemudian melakukan pembaruan kita pada utas GUI, yang ditangani dengan Activity.RunOnUIThread:
public class ThreadDemo : Activity
{
TextView textview;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create a new TextView and set it as our view
textview = new TextView (this);
textview.Text = "Working..";
SetContentView (textview);
ThreadPool.QueueUserWorkItem (o => SlowMethod ());
}
private void SlowMethod ()
{
Thread.Sleep (5000);
RunOnUiThread (() => textview.Text = "Method Complete");
}
}
Kode ini berfungsi seperti yang diharapkan. GUI ini tetap responsif dan diperbarui dengan benar setelah perhitungan dikompleksi.
Perhatikan teknik ini tidak hanya digunakan untuk menghitung nilai yang mahal. Ini dapat digunakan untuk tugas jangka panjang yang dapat dilakukan di latar belakang, seperti panggilan layanan web atau mengunduh data internet.