Duyarlı Uygulamalar Yazma

Duyarlı GUI'yi korumanın anahtarlarından biri, GUI'nin engellenmemesi için arka plan iş parçacığında uzun süre çalışan görevler yapmaktır. Kullanıcıya görüntülenecek bir değeri hesaplamak istediğimizi, ancak bu değerin hesaplanması 5 saniye sürdüğünü düşünelim:

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şlem çalışır, ancak değer hesaplanırken uygulama 5 saniye boyunca "askıda kalır". Bu süre boyunca uygulama hiçbir kullanıcı etkileşimine yanıt vermez. Bu sorunu çözmek için hesaplamalarımızı arka plan iş parçacığı üzerinde yapmak istiyoruz:

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 vermeye devam edebilmesi için arka plan iş parçacığındaki değeri hesaplıyoruz. Ancak hesaplama yapıldığında uygulamamız kilitlenir ve bunu günlükte bırakır:

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'yi güncelleştirmeniz gerekir. Kodumuz ThreadPool iş parçacığından GUI'yi güncelleştirir ve uygulamanın kilitlenmesine neden olur. Arka plan iş parçacığındaki değerimizi hesaplamamız gerekiyor, ancak ardından güncelleştirmemizi Activity.RunOnUIThread ile işlenen GUI iş parçacığında gerçekleştirin:

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. Bu GUI yanıt vermeye devam eder ve hesaplama tamamlandıktan sonra düzgün bir şekilde güncelleştirilir.

Bu tekniğin yalnızca pahalı bir değeri hesaplamak için kullanılmamış olduğunu unutmayın. Bir web hizmeti çağrısı veya internet verilerini indirme gibi arka planda gerçekleştirilebilecek uzun süre çalışan herhangi bir görev için kullanılabilir.