Questo è stato chiesto in una delle interviste Android. Mi è stato chiesto se è possibile avviare un'altra attività asincrona (lasciatelo Task2) dal metodo doInBackground() dell'attività asincrona 1 (lascia che sia Task1). Ho esaminato i documenti che dicono quanto segue:Task asincrono Android eseguito
L'istanza dell'attività deve essere creata sul thread dell'interfaccia utente.
execute (Params ...) deve essere richiamato sul thread dell'interfaccia utente.
Come da queste dichiarazioni, penso che non dovrebbe essere possibile avviare un'attività dal metodo in background di un'altra attività. Inoltre, l'attività asincrona ha metodi UI (che non possono essere usati su un thread in background), in modo da rafforzare la mia argomentazione e io non ho risposto.
Controllando su una semplice app demo, ho visto che è davvero possibile farlo. Alcuni codice dimostrativo:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
init();
Log.v ("gaurav", "Thread is : " + Thread.currentThread().getName());
Task1 task = new Task1();
task.execute();
}
class Task1 extends AsyncTask {
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
Log.v ("gaurav", "Thread task 1 is : " + Thread.currentThread().getName());
Task2 task = new Task2();
task.execute();
return null;
}
}
class Task2 extends AsyncTask {
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
Log.v ("gaurav", "Thread task 2 is : " + Thread.currentThread().getName());
Log.v ("gaurav", "Task 2 started");
return null;
}
}
ottengo seguenti registri che indicano l'esecuzione con successo:
> 08-07 09:46:25.564: V/gaurav(2100): Thread is : main 08-07
> 09:46:25.564: V/gaurav(2100): Thread task 1 is : AsyncTask #3 08-07
> 09:46:25.564: V/gaurav(2100): Thread task 2 is : AsyncTask #4 08-07
> 09:46:25.564: V/gaurav(2100): Task 2 started
ho controllato questo su ICS, KK e dispositivo L e tutto funziona bene per tutti.
Uno dei motivi per cui posso pensare è che non sto eseguendo l'override dei metodi dell'interfaccia utente e non eseguo alcun aggiornamento dell'interfaccia utente nella mia seconda attività, quindi non causa problemi, ma non ne sono sicuro. Anche se questo è il caso, viola le regole di threading menzionate nella guida per gli sviluppatori.
Come riferimento, ho verificato anche questo collegamento: Start AsyncTask from another AsyncTask doInBackground() ma la risposta afferma di avviare la seconda attività utilizzando il metodo runOnUiThread() all'interno di doInBackground(). Vorrei un po 'di aiuto su cosa sta succedendo qui. Grazie.
Un'altra ragione per cui ho utilizzato domande simili nelle interviste è determinare se il candidato k per quanto riguarda l'interruzione delle modifiche del comportamento dei thread in AsyncTasks da Honeycomb verso l'alto: http://stackoverflow.com/questions/21165505/mutliple-asynctasks-with-sequential-execution – adelphus
@adelphus, non riuscivo a capire il significato di "A partire da HONEYCOMB, le attività vengono eseguite su un singolo thread per evitare errori di applicazione comuni causati dall'esecuzione parallela. " Definisce l'esecuzione seriale, ma le attività nidificate avrebbero ancora il loro onPreExecute()/onPostExecute() eseguito sul thread in background nel contesto della mia domanda? O come dice la risposta sotto riportata sul carico della classe all'avvio dell'app, in quel caso i metodi onPre/onPost di tutte le attività nidificate vengono eseguiti sul thread dell'interfaccia utente indipendentemente da dove è stata avviata l'attività? –
Qui ci sono due problemi: il mio commento sta parlando del fatto che più AsyncTasks venivano usati in parallelo con 1 thread per task. Dal momento che Honeycomb, più AsyncTasks sono ora accodati in modo che vengano eseguiti tutti su un singolo thread: solo 1 può essere eseguito alla volta. Il cambiamento ha infranto un sacco di codice perché gli sviluppatori hanno assunto compiti eseguiti in parallelo. La tua domanda sull'esecuzione di onPreExecute/onPostExecute sul thread dell'interfaccia utente è un problema diverso, ma yaa110 lo descrive bene nella sua risposta. – adelphus