AsyncTask yapısının doğru kullanımı nasıl olmalıdır?
Genel olarak Android uygulama geliştirirken gördüğüm en önemli yanlış davranışlardan birisi de AsyncTask yapısının kullanımı ile ilgili. Burada bazı yanlış anlamalar mevcut. Bunun en başlıca sebeplerinden bir tanesi ise, Android uygulama geliştirmeye yeni başlamış olan geliştiricilerin, tam olarak Android Lifecycle yapısını anlamadan işlemlerini thread kullanarak yapmaya kalmışları. İşte bu durumlar tam olarak kontrol altına alınmadığı zaman ise, AsyncTask yapısı sizin için tam bir baş ağrısı olacaktır. Genel olarak da bundan dolayı yeni başlayanlara, AsyncTask kullanımından uzak durmalarının söylendiğini de görebiliriz.
Bu yazı boyunca sizlere AsyncTask yapısını nasıl kullanabileceğinizi ve bahsedilen sorunlardan nasıl uzak durabileceğinizi göstereceğim.
Genel fikirliğinin bizlere söylediği üzere, AsyncTask işlemleri uzun süreli tasklar için değildir. Yine de ne kadar sürdüğüne bakılmaksızın, basit bir task işlemini gerçekleştirmek isteyebilirsiniz. Benim düşünceme göre, AsyncTask bunun için son derece uygundur.
Genel bilinen bir yanlış
Android uygulama geliştirmeye yeni başlayan veya çok fazla tecrübesi olmayan geliştiricilerin yaklaşımı kısaca aşağıda ki gibi gösterilebilir.
Bu kullanımda ki en temel yanlışlardan bir tanesi, AsyncTask belirtilen Activity’e implicit reference kullanarak bağlanmış durumdadır. Uygulama içerisinde herhangi bir configuration değişimi meydana gelecek olursa, AsyncTask’ ı çalıştırmış olan Activity’e ait olan instance destroy edilecek ancak GC tarafından AsyncTask işlemi bitene kadar temizlenmeyecektir. Asıl problem de burada ortaya çıkmaktadır. Pek çok Asynctask oluşturulduğu durumda, bellek sorunları oluşacaktır. Bir başka sorun ise, Asynctask’ ın döniş değeri, Activity ile bağlı bir durum ise kaybolabilir.
Peki Ne Yapmalı?
Burada pek çok yaklaşım sergilenebilir. Benim ve aslında bir çok developer’ in tercihi bir event bus kullanmaktır. Kişisel olarak Square ve Jack Wharton hayranlığından dolayı Otto’ yu tercih etmekteyim. Temel olarak yapacaklarımızı özetleyecek olursak,
İlk olarak Asynctask yapısını kendi sınıfının içerisine taşımalıyız. Daha sonra AsyncTask işlemi bitince çalışacak olan bir event tanımlamalıyız. En son olarak bu event’ i dinleyecek olan Activity içerisinde Subscribe işlemini gerçekleştirmeliyiz.
Otto kullanımı oldukça basittir. Kullanabilmek için bir tane singleton yapıda helper sınıfı tanımlamalıyız. (Burada da birbirine yakın olmakla birlikte bir takım farklı kullanım yöntemleri bulunmaktadır.)
Bu örnek için basit bir event tanımlayacak olursak;
Bütün bu event tanımlamalarından sonra basit bir işlem gerçekleştiren AsyncTask sınıfını yeniden yazalım.
Şimdi sıra geldi bu yazılan Asnctask sınıfını çalıştıracak ve oradan dönen değeri yakalayacak olan Activity sınıfını yazmaya. Kısa bir örnek olması açısından sanırım aşağıda ki kod örneği yeterli olacaktır.
İşlem tamam. Şimdi tekrar baktığımızda göreceğiz ki artık AsyncTask hard reference bir yapı ile bağlı değil. Bu durumda herhangi bir memory leaking görünmüyor. Herhangi bir configuration değişimi olursa, event bus yapısına activity içerisinde register olduğumuzdan dolayı, task sonucundan otomatik olarak haberdar olacağız.
Sonuç olarak,
Event bus kullanımın avantajlı olduğu durumlar sadece AsyncTask yapısından ibaret değildir. Benzeri durumlar Service kullanımı sırasında da görülebilir. Event bus yapısının kullanımı burada da karşınıza çıkabilecek olan sorunları çözecektir.