İşleyici ve AsyncTask


128

Bir Handler yerine AsyncTask'ı ne zaman seçeceği konusunda kafam karıştı. Her n saniyede bir çalıştırmak istediğim ve kullanıcı arayüzünü güncelleyecek bir kodum olduğunu varsayalım. Neden birini diğerine tercih edeyim?


1
Bu, AsyncTaskLoaders ile daha karmaşık hale geldi. Daha fazla bilgi için stackoverflow.com/q/7120813/969325 sayfasına bakın .
Warpzit

Yanıtlar:


75

IMO, AsyncTask, düşük seviyeli ayrıntılar (iş parçacıkları, mesaj döngüleri vb.) Hakkında çok fazla endişelenmeden, Android uygulamalarında arka planda işlemeyi başarmak için uygun, kullanımı kolay bir yol sağlamak için yazılmıştır. Görevleri planlamaya ve ayrıca gerektiğinde kullanıcı arayüzünü kolayca güncellemeye yardımcı olan geri arama yöntemleri sağlar.

Bununla birlikte, AsyncTask'ı kullanırken, bir geliştiricinin, sınıfın yazarının aldığı tasarım kararları nedeniyle ortaya çıkan sınırlamalarına boyun eğdiğini not etmek önemlidir. Örneğin, yakın zamanda AsyncTasks kullanılarak planlanabilen işlerin sayısında bir sınır olduğunu öğrendim.

İşleyici ikisi hakkında daha şeffaftır ve muhtemelen size daha fazla özgürlük verir; bu yüzden, işler üzerinde daha fazla kontrol istiyorsanız, İşleyiciyi seçersiniz, aksi takdirde AsynTask gayet iyi çalışacaktır.


Doğru. Projemdeki tüm arka plan işlemleri için AsyncTasks kullanıyordum. Bir noktada bu maksimum iş sınırına ulaşmaya başladım, böylece görevlerim ancak bir başkası bittikten sonra başlayacaktı. Sonunda, eşzamansız görevler kullanmayı bırakmak ve bu sınırlamaya ulaşmaktan kaçınmak için tüm yapımı değiştirmek zorunda kaldım.
tbraun

5
Honeycomb'dan itibaren AsyncTasks, tek bir iş parçacığı üzerinde yürütülür, bu nedenle artık paralellik yoktur. Bunları yine de paralel bir Executoruygulama üzerinde çalıştırabilirsiniz .
MrSnowflake

63

Benim temel kuralım şöyle olurdu:

  • UI ile ilgili izole bir şey yapıyorsanız, örneğin bir listede sunmak için veri indirmek istiyorsanız, devam edin ve kullanın AsyncTask.

  • Birden çok yinelenen görev yapıyorsanız, örneğin indirme sırasında görüntülenecek birden fazla görüntüyü ImageViewsindirmek (küçük resimleri indirmek gibi), ile bir görev kuyruğu kullanın Handler.


İşleyici API seviyesi 1'de ve ASYNCTASK API seviyesi 3'te. Ne pahasına olursa olsun kullanımdan kaldırılacak mı? becaz uygulamaları eski sürümlerden 2.2 ve 2.3'e
taşımaya odaklanıyorum

10
İkisi de yakın zamanda kullanımdan kaldırılmayacak. Kullanıcı arabirimi temelde onun etrafında oluşturulduğundan, işleyici asla kullanımdan kaldırılmayacaktır.
alexanderblom

Kullanıcı arayüzünüzün sunması için verileri yüklemek için bir Yükleyici kullanmanız gerekmez mi?
nbarraille

19

AsyncTask'ı mümkün olduğunda özellikle aşağıdaki nedenlerden dolayı kullanmaktan kaçınmaya çalışın:

  • Sistem tarafından ayarlanan bir ThreadPool tabanı ve maksimum boyut olduğu için AsyncTask'ın çalışması garanti edilmez ve çok fazla asynctask oluşturursanız, sonunda yok edilirler.

  • AsyncTask, etkinlik yaşam döngüsüne bağlı olarak çalışırken bile otomatik olarak sonlandırılabilir ve üzerinde hiçbir kontrolünüz yoktur.

  • OnPostExecute gibi UI Thread üzerinde çalışan AsyncTask metotları, atıfta bulunduğu Aktivite artık görünmediğinde veya muhtemelen bir oryantasyon değişikliğinden sonra olduğu gibi farklı bir düzen durumunda olduğunda yürütülebilir.

Sonuç olarak, ana avantajı olan UIThread bağlantılı AsyncTask yöntemlerini kullanmamalısınız !!! Dahası, doInBackground üzerinde yalnızca kritik olmayan çalışmalar yapmalısınız. Bu sorunlarla ilgili daha fazla bilgi için bu diziyi okuyun:

AsyncTask gerçekten kavramsal olarak kusurlu mu yoksa sadece bir şeyi mi kaçırıyorum?

Sonuç olarak, yukarıda belirtilen sorunlardan herhangi biri sizin için önemliyken AsyncTask yerine IntentServices, HandlerThread veya ThreadPoolExecutor kullanmayı tercih etmeyi deneyin. Elbette daha fazla çalışma gerektirecek, ancak başvurunuz daha güvenli olacak.


Evet, AsyncTasks'in birçok kullanımından pişmanlık duyarak çok zaman harcadım. Harika görünüyorlar, ama ... pek çok sorun!
SMBiggs

6
Puanlarınıza karşı bu kadar güçlü bir şekilde yazdığım için özür dilerim, ancak zayıf tarzınızın android üzerinde noobies etkilemesine izin veremem. Birinci nokta. Çalışan bu kadar çok iş parçacığına sahip OLMAMALISINIZ. Eğer bununla karşılaşırsanız, mimariniz saçmadır. Nokta 2. Nasıl olur da .. Tamam, evet, android'deki her şey çöp toplayıcı için ücretsiz bir oyundur ... Yukarıda açıklandığı gibi, yalnızca görevi kötüye kullanan bazı durumlarda abserd davranışlar görürsünüz. Nokta 3. Görevinizi yönetmek, kaba olmamak, acemi bir beceridir. Ya onPause'u çağırdığınızda onu öldürürsünüz ya da uygun şekilde ayırıp bağlarsınız.
StarWind0

1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html Yukarıdaki sorunlar olmadan görevleri düzgün bir şekilde nasıl yapacağınızı öğrenmek için ihtiyacınız olan tek şey budur (birkaç yüz görevi bitirmek gibi bir şey yapmadığınızı varsayarak)
StarWind0

16

Her x saniyede bir hesaplama yapmak istiyorsanız, muhtemelen Runnablea Handler(with postDelayed()) için bir hesaplamalısınız ve bu Runnablegeçerli UI iş parçacığında başlamalıdır. Başka bir iş parçacığında başlatmak istiyorsanız, HandlerThread kullanın. AsyncTask bizim için kullanımı daha kolay ama işleyiciden daha iyi değil.


7

İşleyici, uygulamanın ana iş parçacığı ile ilişkilidir. Arka plandaki iş parçacıklarından uygulama ana iş parçacığına gönderilen mesajları ve çalıştırılabilirleri işler ve planlar.

AsyncTask, zaman alan işlemlerle onu engellemeden UI'yi güncellemek için arka plan iş parçacıklarını işlemek için basit bir yöntem sağlar.

Cevap, her ikisinin de kullanıcı arayüzünü arka plan iş parçacıklarından güncellemek için kullanılabileceğidir, fark yürütme senaryonuzda olacaktır. İşleyiciyi kullanmayı düşünebilirsiniz, gecikmeli mesajlar göndermek veya MessageQueue'ya belirli bir sırayla mesajlar göndermek isteyebilirsiniz.

Uygulama ana iş parçacığı ile arka plan iş parçacığı arasında kolay ve rahat bir şekilde parametreleri değiştirmek (dolayısıyla kullanıcı arabirimini güncellemek) istiyorsanız AsyncTask kullanmayı düşünebilirsiniz.


3
Başka bir İş Parçacığı ile ilişkilendirilmiş kendi İşleyicinizi oluşturabilirsiniz.
Aleksejs Mjaliks

İşleyicinin ana iş parçacığına (UI İş Parçacığı) bağlı olması gerekmez. Oluşturulduğu iş parçacığına bağlıdır ve bu iş parçacığı ileti kuyruğuna ulaşan Message's veya Runnable'ları işler. Ayrıca bu iş parçacığı mesaj kuyruğuna Mesaj ve Çalıştırılabilir nesneler gönderebilir.
azec-pdx

2

AsyncTaskbazı arka plan çalışmaları bittikten sonra UI iş parçacığında bir şeyler yapacağınızı varsayar. Ayrıca, yalnızca bir kez çalıştırabilirsiniz (bundan sonra, durumu olur FINISHEDve bir kez daha çalıştırmaya çalışırken bir istisna alırsınız). Ayrıca, kullanma esnekliği çok fazla değil. Evet, THREAD_POOL_EXECUTORparalel bir yürütme için kullanabilirsiniz , ancak çabaya değmeyebilir.

HandlerÇalıştırılabilir Öğeleri ve Mesajları işleme dışında hiçbir şeyi varsaymaz. Ayrıca istediğiniz kadar çalıştırılabilir . Hangi iş parçacığına bağlanması gerektiğine, diğer işleyicilerle nasıl iletişim kuracağına, belki onları üretmekte özgürsünüz HandlerThread. Bu nedenle, çok daha esnek ve tekrarlanan bazı işler için uygundur.

Burada farklı türden Handlerörnekleri kontrol edin .


0

Sorulan en iyi röportaj sorusudur. AsyncTask - UI iş parçacığını boşaltmak ve arka planda görevleri yapmak için kullanılırlar. İşleyiciler - Android dosent, kullanıcı arayüzü ve arka plan iş parçacığı arasında doğrudan iletişim yoluna sahiptir. İşleyiciler, mesaj göndermek veya mesaj kuyruğu aracılığıyla çalıştırılabilir olmak için kullanılmalıdır.

Bu nedenle AsyncTasks, görevlerin arka planda yürütülmesi gerektiğinde kullanılır ve İşleyiciler, bir UI ile Arka Plan İş Parçacığı arasındaki iletişim için kullanılır.


0

doInBackground - temelde başka bir iş parçacığında çalışır. onPostExecute - sonuçları UI iş parçacığında gönderir ve dahili olarak ana iş parçacığının işleyicisine mesaj gönderir. Ana UI iş parçacığının zaten kendisiyle ilişkilendirilmiş bir döngüleyici ve işleyicisi var.

Temel olarak, bazı arka plan görevleri yapmanız gerekiyorsa, AsyncTask kullanın. Ancak nihayetinde, UI'de bir şeyin güncellenmesi gerekiyorsa, ana iş parçacığının işleyicisini kullanacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.