AsyncTask konuları asla ölmez


112

AsyncTaskKullanıcının bir düğmeye basmasına yanıt olarak verileri almak için s kullanıyorum . Bu iyi çalışıyor ve verileri getirirken arayüzü yanıt verirken tutuyor, ancak Eclipse hata ayıklayıcısında neler olup bittiğini kontrol ettiğimde, her yenisinin AsyncTaskoluşturulduğunu öğrendim (ki bu oldukça sık, çünkü bunlar yalnızca bir kez kullanılabilir) ), yeni bir iş parçacığı oluşturuluyordu ancak hiçbir zaman sonlandırılmadı.

Sonuç, AsyncTaskorada oturan çok sayıda iş parçacığıdır. Bunun pratikte bir sorun olup olmadığından emin değilim, ancak bu ekstra ipliklerden gerçekten kurtulmak istiyorum.

Bu konuları nasıl öldürebilirim?


"Hiç sona ermedi" ile ne demek istiyorsun? Görev, doInbackground yöntemini hiçbir zaman sonlandırmıyor mu yoksa ayırma izleyicide asynctask nesnesini mi görüyorsunuz?
Francesco Laurita

7
doInBackgroundYöntem tamamlar, ancak iplik hata ayıklama penceresinde göstermek devam ediyor. Örneğin: Thread [<23> AsyncTask #4](Running)
Computerish

Yanıtlar:


202

AsyncTask ile oluşturulan bir iş parçacığı havuzunu yönetir ThreadPoolExecutor . 5 ila 128 iş parçacığı olacak. 5'ten fazla iplik varsa, bu ekstra iplikler çıkarılmadan önce en fazla 10 saniye etrafta kalacaktır. (not: bu rakamlar halihazırda görünen açık kaynak kodu içindir ve Android sürümüne göre değişiklik gösterir).

İpleri AsyncTaskrahat bırakın lütfen.


Açıklama için teşekkürler! Yanlış bir şey yapmadığımı bilmekten memnunum. Meraktan, neden böyle tasarlandı? Neden tüm yöntemler geri döndükten sonra iş parçacıklarını sonlandırmıyorsunuz?
Computerish

7
Muhtemelen sonraki isteklerde iş parçacığı için zaman kazanmak için.
CommonsWare

@CommonsWare Bazı işlemleri gerçekleştirmek için bir AsyncTask çalıştırdığım bir hizmetim var ve servis widget düğmesine basıldığında başlar ve görev bittiğinde servie'yi hemen durdurması gerekir, ancak bazen AsyncTask ölmez, bu yüzden u bunu nasıl durduracağımı söyle
Hunt

1
@SreekanthKarumanaghat: AsyncTaskBu kadar uzun sürecek bir şey için an kullanmak genel olarak kötü bir fikirdir. Ama hayır, artık fazladan iş parçacığı hakkındaki yorumum, kullanılmadıkları zamandır. Bu nedenle, 6 görevinizden biri bittiğinde, iş parçacığı havuzda 10 saniye kalacak ve ardından iş parçacığı sonlandırılacaktır.
CommonsWare

1
@SreekanthKarumanaghat: "Benim sorum Paralelde 20 (diyelim) AsyncTasks çalıştırmak için herhangi bir kısıtlama olup olmadığı?" - AsyncTaskbugünden önemli ölçüde yararlanmak harika bir plan değil. 10 saniyeden fazla çalışabilen 20'den fazla şeye sahip olmak, bir kod incelemesinde başarısız olması gereken bir şeydir. Art arda 20 görev oluşturursanız, yalnızca birkaçı aynı anda çalışır ve geri kalanı daha sonra yürütülmek üzere kuyruğa alınır. Bir seferde kaç tane çalışacağı CPU'nun çekirdek sayısına bağlıdır. AFAIK, mevcut algoritma 2N + 1 paralel iş parçacığıdır, burada N çekirdek sayısıdır.
CommonsWare

24

CommonsWare'in yanıtına ek olarak:

Şu anda Android 2.2 kullanıyorum ve uygulamam herhangi bir zamanda birden fazla AsyncTask kullanmıyor, ancak her x dakikada bir yeni bir tane oluşturuyorum. İlk başta yeni AsyncTask Threads görünmeye başlar (yeni bir AsyncTask için yeni bir İş Parçacığı) ancak 5 iş parçacığından sonra (CommonsWare tarafından belirtildiği gibi) hata ayıklama penceresinde görünür kalırlar ve yeni AsyncTask iş parçacıkları gerektiğinde yeniden kullanılırlar. Hata ayıklayıcının bağlantısı kesilene kadar orada kalırlar.


2
Evet, onaylandı: 5'ten fazla AsyncTasks görmüyorum.
Seraphim

3

Burada aynı belirti. Benim durumumda, Aktiviteyi öldürdükten sonra iş parçacıkları ortalıkta dolandı ve Uygulamanın tamamen kapanmasını umuyordum. Tek iş parçacıklı bir yürütücü kullanılarak kısmen çözülen sorun:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

Bu, işini tamamladıktan sonra ipliğin kaybolmasına neden oldu.


Bu cevap, AsyncTask'ın çalıştıktan sonra ortadan kalkmasına neden oldu, belki de "işleri yapmanın google yolu" değil ama işi hallediyor. Teşekkür ederim.
Henrique de Sousa

Bu, Asynctasks'i tek bir iş parçacığında çalıştırmayla ilgili özel sorunumu çözdü.
Law Gimenez

0

ThreadPoolExecutor'u kullanın .

BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

Execute () yöntemini Runnablekullanarak görevinizi gönderin .

void execute (Runnable command)

Verilen görevi gelecekte bir ara yürütür. Görev, yeni bir iş parçacığında veya havuza alınmış mevcut bir iş parçacığında yürütülebilir

İkinci sorgunuzla ilgili olarak:

Bu konuları nasıl öldürebilirim?

Tüm çalışmalarınızı ThreadPoolExecutortamamladığınızda, aşağıdaki gönderide belirtildiği gibi düzgün bir şekilde kapatın:

Java ExecutorService nasıl düzgün şekilde kapatılı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.