2012-02-25 20 views

risposta

13

Sulla possibilità è quella di utilizzare gli ascoltatori, in cui si crea un'interfaccia che i vostri implents attività, qualcosa di simile:

public interface AsyncListener { 
    public void doStuff(MyObject obj); 
} 

In questo modo, Se stai sottoclassi AsyncTask, è facile aggiungere questo listener, quindi in onPostExecute(), potresti fare qualcosa del tipo:

protected void onPostExecute(MyObject obj) { 
    asyncListener.doStuff(obj); 
} 
6

Questo dipende dalla struttura della classe, ma se AsyncTask è una classe all'interno della tua attività, puoi fare riferimento ai metodi di tale attività. Cosa si dovrebbe fare è nel metodo OnPostExecute chiamare una funzione della vostra attività che passa un po 'di dati che sono stati recuperati nel AsyncTask all'attività dove è quindi possibile utilizzare esso ..

Il codice sarebbe simile a questa

class YourActivity extends Activity { 
    private static final int DIALOG_LOADING = 1; 

    public void onCreate(Bundle savedState) { 
    setContentView(R.layout.yourlayout); 
    showDialog(DIALOG_LOADING);  
    new LongRunningTask1().execute(1,2,3); 

    } 

    protected Dialog onCreateDialog(int dialogId) { 
    switch(dialogId) { 
     case DIALOG_LOADING: 
      ProgressDialog pDialog = new ProgressDialog(this); 
      pDialog.setTitle("Loading Data"); 
      pDialog.setMessage("Loading Data, please wait..."); 
      return pDialog; 
     default: 
      return super.onCreateDialog(dialogId); 
     }  
    } 

    private void onBackgroundTaskDataObtained(List<String> results) { 
     dismissDialog(DIALOG_LOADING); 
    //do stuff with the results here.. 
    } 

    private class LongRunningTask extends AsyncTask<Long, Integer, List<String>> { 
     @Override 
     protected void onPreExecute() { 
      //do pre execute stuff 
     } 

     @Override 
     protected List<String> doInBackground(Long... params) { 
      List<String> myData = new ArrayList<String>(); 
      for (int i = 0; i < params.length; i++) { 
       try { 
        Thread.sleep(params[i] * 1000); 
        myData.add("Some Data" + i); 
       } catch(InterruptedException ex) { 
       }     
      } 
      return myData; 
     } 

     @Override 
     protected void onPostExecute(List<String> result) { 
      YourActivity.this.onBackgroundTaskDataObtained(result); 
     }  
    } 

} 

Quindi il flusso tipico è simile a questo, imposta la vista della pagina corrente e quindi mostra una finestra di avanzamento. Subito dopo inizia il task asincrono (o quando, non importa davvero).

Una volta completata l'attività asincrona, chiamare una funzione dell'attività e passarla ai dati. Non utilizzare i dati condivisi all'interno dell'attività asincrona o rischi di problemi con la filettatura. Al contrario, una volta terminato, passalo all'attività. Se si desidera aggiornare la vista progressivamente mentre si fa il lavoro è possibile utilizzare sul onProgressUpdate

+0

Grazie per la risposta. Non sono un fan di AsyncTask utilizzato come sottoclasse. Penso che dovresti essere in grado di usare gli eventi. Penso che la risposta stia usando intenti ma creerò solo una nuova istanza della mia attività che non desidero. – skinnybrit51

+0

È possibile utilizzare facilmente AsyncTask nella propria classe, ma è utile solo se si utilizza la stessa logica da più attività diverse. In tal caso è possibile: 1. utilizzare una classe di base comune (non un'attività ma qualcosa che si estende attività) e quindi avresti un metodo comune che potrebbe essere chiamato dal task asincrono. O meglio ancora, entrambi hanno implementato un'interfaccia comune che ha il callback come ho descritto. Passa un riferimento all'attività nel costruttore di AsyncTask e assicurati che asyncTask abbia un costruttore che accetta un parametro del tipo di interfaccia. –

+0

L'ultima opzione è quella di abbandonare completamente AsyncTask e inserirlo in un servizio che è necessario creare un nuovo thread per eseguire l'attività in background (poiché i servizi non verranno eseguiti in proprio thread per impostazione predefinita). Un modo semplice per farlo è creare un IntentService che crei un nuovo thread per te. –

Problemi correlati