web-dev-qa-db-fra.com

Les threads AsyncTask ne meurent jamais

J'utilise AsyncTasks pour récupérer des données en réponse à l'utilisateur qui appuie sur un bouton. Cela fonctionne bien et maintient l'interface réactive tout en récupérant les données, mais lorsque j'ai vérifié ce qui se passait dans le débogueur Eclipse, j'ai découvert que chaque fois qu'une nouvelle AsyncTask était créée (ce qui est assez souvent, car elles ne peuvent une fois), un nouveau thread était en cours de création mais jamais terminé. 

Le résultat est un grand nombre de threads AsyncTask qui restent assis. Je ne sais pas si c'est un problème dans la pratique ou pas, mais j'aimerais vraiment me débarrasser de ces fils supplémentaires. 

Comment puis-je tuer ces discussions?

112
Computerish

AsyncTask gère un pool de threads, créé avec ThreadPoolExecutor. Il aura de 5 à 128 fils. S'il y a plus de 5 threads, ces threads supplémentaires resteront collés au maximum pendant 10 secondes avant d'être supprimés. (Remarque: ces chiffres concernent le code source ouvert actuellement visible et varient en fonction de la version Android).

Laissez les fils AsyncTask seuls, s'il vous plaît.

200
CommonsWare

En plus de la réponse de CommonsWare:

Actuellement, j'utilise Android 2.2 et mon application n'utilise pas plus d'une tâche asynchrone à la fois, mais j'en crée une nouvelle toutes les x minutes. Au début, de nouveaux threads AsyncTask commencent à apparaître (un nouveau thread pour un nouvel asyncTask), mais après 5 threads (comme indiqué par CommonsWare), ils restent visibles dans la fenêtre de débogage et sont réutilisés lorsque de nouveaux threads AsyncTask sont nécessaires. Ils restent là jusqu'à ce que le débogueur se déconnecte.

23
Tom de Waard

Même symptôme ici. Dans mon cas, les discussions ont traîné après que j'ai tué l'activité, et j'espérais que l'application se ferme complètement. Problème partiellement résolu en utilisant un seul exécutant threadé:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

Cela a fait disparaître le fil après l'achèvement de son travail.

3
karnbo

Utilisez ThreadPoolExecutor .

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

Publiez votre tâche Runnable en utilisant execute () method.

void execute (Runnable command)

Exécute la tâche donnée dans le futur. La tâche peut s'exécuter dans un nouveau thread ou dans un thread en pool existant

Concernant votre seconde requête:

Comment puis-je tuer ces discussions?

Une fois que vous avez terminé tout votre travail avec ThreadPoolExecutor, arrêtez-le correctement, comme indiqué dans l'article ci-dessous:

Comment arrêter correctement Java ExecutorService

0
Ravindra babu