2012-12-17 5 views
20

Nella mia applicazione ho uno SplashActivity che esegue alcune operazioni utilizzando AsyncTask quando avvio la mia applicazione.parallelo in esecuzione AsyncTask

Ho anche creato un altro AsyncTask che scarica i dati dal server. Ora, dopo aver chiuso la mia applicazione, AsyncTask sta ancora scaricando i dati.

Ma quando riavvio la mia applicazione AsyncTask di SplashActivity non esegue il suo background (funzione doInBackground) finché il mio downloader AsyncTask non è terminato e la mia applicazione è impiccata.

Quindi la mia domanda è che non possiamo eseguire due parallelo AsyncTask? Entrambi AsyncTask sono diversi e fanno le loro cose. C'è un modo per farlo.

+0

Si prega di inviare il codice relativo (Attività e attività di chiamata) –

risposta

30

È necessario utilizzare per eseguire AsyncTask. implementazione predefinita utilizza un esecutore di serie in esecuzione su un singolo thread

Quindi creare un ThreadPoolExecutor e quindi utilizzare

AsyncTask di executeOnExecutor invece di eseguire il metodo

+0

C'è qualche tipo di svantaggio utilizzando questo metodo. Cioè devi fare del lavoro extra rendendo parallelo AsyncTask? –

+2

@ Gee.E l'utilizzo dell'esecutore predefinito è migliore poiché c'è solo un thread istanziato, quindi se non si hanno troppe attività in esecuzione nello stesso momento, l'esecutore predefinito offre prestazioni migliori, ma se c'è un asynctask che richiede molte di tempo, potrebbe essere necessario un ThreadPoolExecutor – nandeesh

+0

@nandeesh Roger, sto utilizzando l'attività parallela per recuperare i dati da un database memorizzato nella cache. Per motivi complessi ho bisogno che il task fetcher esegua parallelamente, ma poiché il tempo necessario è trascurabile, non vedo alcun calo di prestazioni. Indipendentemente da ciò, grazie per aver spiegato il problema. –

35

C'è stato un cambiamento di AsyncTask dal rilascio di Honeycomb. Le versioni precedenti avevano un pool di thread di 10 thread, quindi è possibile eseguire 10 attività in parallelo. Ma per Honeycomb e up, default è un executor seriale, che esegue i task uno per uno. Ma è possibile passare un ThreadPoolExecutor per l'esecuzione:

if (Build.VERSION.SDK_INT >= 11) { 
    //--post GB use serial executor by default -- 
    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
    } else { 
    //--GB uses ThreadPoolExecutor by default-- 
    task.execute(); 
    } 
+3

Non è necessario specificare l'ultimo argomento 'new Void [] {}'; ometterlo sarà sufficiente. –

+0

Il tuo IDE è sbagliato; le vararg sono scorciatoie per creare array, quindi ovviamente l'elenco dei parametri può essere vuoto. In effetti, fornire un nuovo array come quello che hai è in realtà una cattiva pratica; stai istanziando inutilmente un oggetto. Il GC dovrà venire in giro e mettere in pausa la tua app per alcuni millisecondi per ripulirlo. –

+0

Grazie! Funziona come un fascino. E la documentazione di Android non potrebbe essere più chiara su questo: "Esecutore finale statico pubblico THREAD_POOL_EXECUTOR .Aggiunto in API livello 11 - Un esecutore che può essere utilizzato per eseguire attività in parallelo." – Luis

5

Un'altra opzione sta usando AsyncTaskCompat dalla libreria di supporto v.4.

AsyncTaskCompat.executeParallel(new AsyncTask<Void, Void, Object>() { 
    @Override 
    protected Object doInBackground(Void... params) { 
     // do your parallel task here 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Object result) { 
     // and fetch result 
    } 
}); 
+1

Questa classe era obsoleta nel livello API 26 e rimossa nel livello API 27 –