Duyarlı Uygulamalar Yazma

Duyarlı bir GUI'nin bakımını yapma anahtarlarından biri, GUI'nin engellenmiş olması için arka plan iş parçacığında uzun süre çalışan görevler yapmaktır. Kullanıcıya göstermek için bir değer hesaplamak istiyor ancak bu değerin hesap süresi 5 saniyedir:

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";
    }
}

Bu işe çalışacaktır, ancak değer hesaplanırken uygulama 5 saniye "askıda" olur. Bu süre boyunca, uygulama herhangi bir kullanıcı etkileşimine yanıt vermez. Bunu yapmak için hesaplamalarımızı bir arka plan iş parçacığı üzerinde yapmak gerekir:

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";
    }
}

Şimdi gui'mizin hesaplama sırasında yanıt veriyor olarak kalması için arka plan iş parçacığında değeri hesaplayız. Ancak hesaplama işlemi tamam olduğunda uygulamamız kilitleniyor ve bunu günlükte bırakıyor:

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 ()

Bunun nedeni GUI iş parçacığından GUI'sini güncelleştirmeniz olmasıdır. Kodumuz ThreadPool iş parçacığından GUI'leri günceller ve uygulamanın kilitlenmesine neden olur. Arka plan iş parçacığında değerimizi hesaplamamız gerekiyor, ancak ardından güncelleştirmemizi Activity.RunOnUIThreadile işilen GUI iş parçacığında yapacağız:

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");
    }
}

Bu kod beklendiği gibi çalışır. Hesaplama uygun hale geldiğinde bu GUI yanıt verir ve düzgün bir şekilde güncelleştirilir.

Bu tekniğin yalnızca pahalı bir değeri hesaplamak için kullanılmay olduğunu unutmayın. Web hizmeti çağrısı veya internet verilerini indirme gibi, arka planda yap 2000'den uzun süre çalışan herhangi bir görev için kullanılabilir.