In attesa che l'attività asincrona termini il suo lavoro


86

Sono molto nuovo nella programmazione e ho qualche dubbio.

Ho un AsyncTaskche chiamo come RunInBackGround.

e inizio questo processo come:

new RunInBackGround().execute();

Ma desidero attendere che questa chiamata termini la sua esecuzione, prima di procedere alle altre istruzioni di codice.

Come lo posso fare?

C'è un modo per farlo?


2
Il punto di AsyncTask è che è asincrono, il che significa che non è sincronizzato con il resto del codice.
Gjordis

3
Puoi usare il suo metodo onPostExecute () di AsyncTask per ottenere il callback nella tua classe.
DcodeChef

5
non vuoi davvero aspettare che finisca. Quello che vuoi è sapere quando finisce.
njzk2

3
@DcodeChef è l'unico che ha capito cosa voleva nella domanda.
Please_Dont_Bully_Me_SO_Lords

1
Penso che questa è la risposta che stai cercando stackoverflow.com/questions/13079645/...
user3362415

Risposte:


131

attendere che questa chiamata termini la sua esecuzione

Dovrai chiamare il metodo AsyncTask.get () per ottenere il risultato e attendere che l' doInBackgroundesecuzione non sia completa. ma questo bloccherà il thread dell'interfaccia utente principale se non chiami il metodo get all'interno di un thread .

Per recuperare il risultato nel thread dell'interfaccia utente, inizia AsyncTaskcome segue :

String str_result= new RunInBackGround().execute().get();

3
quindi come aspettare il risultato e non bloccare il thread dell'interfaccia utente principale?! diciamo che il codice aspetta il risultato ma nel frattempo la barra di avanzamento continua a scorrere!
Muhammad Naderi

2
@MuhammadNaderi: Usa AsyncTasksenza getmetodo e in AsyncTask onPostExecuteviene chiamato il metodo che fornisce i risultati sul thread dell'interfaccia utente principale
ρяσsρєя K

3
certo questa è una soluzione alternativa, che sto usando da un po 'di tempo, ma a volte ho bisogno che il codice attenda l'asynctask, qualcosa come awaitin c#, e non ottenga il thread principale bloccato ovviamente
Muhammad Naderi

2
@ ρяσsρєяK grazie, grazie mille. non hai idea di quanto ho tirato i capelli su questo problema tuttavia con un solo .get () ha risolto (mi prendi in giro) solo un .get () !!!!!
Code_Worm

Come puoi usare AsyncTask ed evitare di usare get () per evitare il blocco dell'interfaccia utente?
Arjun Issar

37

Sebbene in modo ottimale sarebbe bello se il tuo codice potesse essere eseguito in parallelo, può essere il caso che tu stia semplicemente usando un thread in modo da non bloccare il thread dell'interfaccia utente, anche se il flusso di utilizzo della tua app dovrà attendere.

Hai praticamente 2 opzioni qui;

  1. Puoi eseguire il codice che vuoi aspettare, nello stesso AsyncTask. Se ha a che fare con l'aggiornamento dell'interfaccia utente (thread), è possibile utilizzare il metodo onPostExecute. Questo viene chiamato automaticamente quando il tuo lavoro in background è finito.

  2. Se per qualche motivo sei costretto a farlo in Attività / Frammento / Qualunque cosa, puoi anche trasformarti in un ascoltatore personalizzato, che trasmetti dal tuo AsyncTask. Usando questo, puoi avere un metodo di callback nella tua Attività / Frammento / Qualunque cosa che viene chiamato solo quando lo vuoi: ovvero quando il tuo AsyncTask ha finito con quello che dovevi aspettare.


6
Questa è una risposta formidabile, dovrebbe essere quella accettata. Anche qui è un esempio di come raggiungere questo obiettivo con AsyncTasks: stackoverflow.com/questions/12575068/...
Jose Gonzalez

nella seconda opzione, nel frattempo lanciate l'intento al ricevitore, il thread principale verrà ripreso a destra. OP non ne ha bisogno.
LincyTonita

16

Nella tua AsyncTaskaggiunta ProgressDialog come:

private final ProgressDialog dialog = new ProgressDialog(YourActivity.this);

puoi impostareMessage in un onPreExecute()metodo come:

this.dialog.setMessage("Processing..."); 
this.dialog.show();

e nel tuo onPostExecute(Void result)metodo elimina il tuo ProgressDialog.


15

AsyncTask ha quattro metodi ..

onPreExecute  -- for doing something before calling background task in Async

doInBackground  -- operation/Task to do in Background

onProgressUpdate  -- it is for progress Update

onPostExecute  -- this method calls after asyncTask return from doInBackground.

puoi chiamare il tuo lavoro su di onPostExecute()esso chiama dopo il ritorno dadoInBackground()

onPostExecute è ciò di cui hai bisogno per implementare.


1

Penso che il modo più semplice sia creare un'interfaccia per ottenere i dati da onpostexecute ed eseguire l'interfaccia utente dall'interfaccia:

Crea un'interfaccia:

public interface AsyncResponse {
    void processFinish(String output);
}

Quindi in asynctask

@Override
protected void onPostExecute(String data) {
    delegate.processFinish(data);
}

Poi nella tua attività principale

@Override
public void processFinish(String data) {
     // do things

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.