2010-06-19 11 views
113

Sto utilizzando AsyncTask s per recuperare i dati in risposta all'utente premendo un pulsante. Funziona bene e mantiene l'interfaccia reattiva durante il recupero dei dati, ma quando ho controllato cosa stava succedendo nel debugger di Eclipse, ho scoperto che ogni volta veniva creato un nuovo AsyncTask (che è abbastanza spesso, perché possono essere usati solo una volta), veniva creato un nuovo thread ma non veniva mai terminato.I thread AsyncTask non muoiono mai

Il risultato è un numero elevato di thread AsyncTask appena seduti lì. Non sono sicuro se questo è un problema nella pratica o no, ma mi piacerebbe davvero liberarmi di quei fili extra.

Come posso eliminare questi thread?

+0

Cosa vuoi dire con "non terminato"? L'attività non termina mai il suo metodo doInbackground o viene visualizzato l'oggetto asynctask nel gestore di allocazione? –

+7

Il metodo 'doInBackground' viene completato, ma il thread continua a essere visualizzato nella finestra di debug. Ad esempio: 'Thread [<23> AsyncTask # 4] (In esecuzione)' – Computerish

risposta

199

AsyncTask gestisce un pool di thread, creato con ThreadPoolExecutor. Avrà da 5 a 128 thread. Se ci sono più di 5 discussioni, quelle discussioni extra rimarranno attaccate per almeno 10 secondi prima di essere rimosse. (nota: queste cifre sono per il codice open source attualmente visibile e variano a seconda della versione di Android).

Lasciare le filettature AsyncTask da sole, per favore.

+0

uff! bene a sentirlo! hehe :) –

+0

Grazie per la spiegazione! Sono felice di sapere che non sto facendo nulla di sbagliato. Per curiosità, perché è progettato in questo modo? Perché non basta terminare i thread dopo che tutti i metodi sono tornati? – Computerish

+7

Presumibilmente per risparmiare tempo a forgiare i thread su richieste successive. – CommonsWare

23

Oltre alla risposta di CommonsWare:

Attualmente sto usando Android 2.2, e la mia applicazione utilizza non più di un AsyncTask in qualsiasi momento, ma sono la creazione di uno nuovo ogni x minuti. Inizialmente appaiono i nuovi Thread AsyncTask (un nuovo Thread per un nuovo AsyncTask) ma dopo 5 thread (come menzionato da CommonsWare) rimangono visibili nella finestra di debug e vengono riutilizzati quando sono necessari nuovi thread AsyncTask. Restano lì fino a quando il debugger si disconnette.

+2

Sì, confermato: non vedo più di 5 AsyncTasks. –

3

Lo stesso sintomo qui. Nel mio caso i thread si sono bloccati dopo che avevo ucciso l'Activity e speravo che l'App si chiudesse completamente. Problema parzialmente risolto utilizzando un singolo esecutore filettato:

myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor()); 

Ciò fatto il filo a svanire dopo il completamento suo lavoro.

+0

Questa risposta ha fatto sparire AsyncTask dopo la sua esecuzione, forse non è il "modo google di fare cose" ma ha portato a termine il lavoro. Grazie. –

+0

Questo ha risolto il mio problema specifico relativo all'esecuzione di Asynctasks su un singolo thread. –

0

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

Inserisci Runnable attività utilizzando execute() metodo.

void execute (Runnable command) 

Esegue il compito affidato in futuro. Il compito può eseguire in un nuovo thread o in un thread pool esistente

quanto riguarda la tua seconda query:

Come posso uccidere questi fili?

Una volta che hai finito con tutto il vostro lavoro con ThreadPoolExecutor, l'arresto in modo corretto, come citato in seguito posta:

How to properly shutdown java ExecutorService

Problemi correlati