2013-03-14 8 views
8

Mi chiedevo se AsyncTask è stato creato per essere utilizzato all'interno dell'attività principale (MainActivity.java) che esegue il thread.Devo utilizzare la classe AsyncTask all'interno dell'attività di estensione MainActivity?

Per esempio ho notato molti tutorial quando si utilizza il AsyncTask dichiarano una classe privata all'interno estendendo la classe principale del Activity piuttosto che creare un file indipendente .java per quella AsyncTask (MyAsyncTask.java) class.

Ma ho notato che quando si utilizza un file indipendente non sto essendo in grado di eseguire il runOnUIThread() perché appartiene alla classe Activity, così come sarò in grado di utilizzare questo metodo all'interno di quella indipendente AsyncTask (MyAsyncTask. java) che si estende AsyncTask e non Activity.

+0

perché si desidera chiamare runOnUIThread da AsyncTask? – EvilDuck

+0

per modificare le visualizzazioni di testo, non possono essere modificate da altri thread. – Alex

+0

È possibile aggiornare l'interfaccia utente in onPostExecute e onPreExecute –

risposta

12

Questo è tutto a posto. Lo faccio spesso ma dipende da come lo stai usando. Se può essere usato da altri Activities allora gli do la sua classe o una classe condivisa. Ma se è per un singolo scopo, farei di esso una classe interna di MainActivity.

Il vantaggio di renderlo una classe interna è che ha accesso diretto alle variabili membro di quella classe. Se si effettua una classe separata, è sufficiente creare un costruttore per questo se è necessario passare params come context o altre variabili.

Non so esattamente cosa si sta facendo ma non sono sicuro che sia necessario runOnUiThread(). Puoi creare un costruttore nel tuo file AsyncTask e fargli accettare context come parametro e qualsiasi altra cosa tu abbia bisogno. Quindi è possibile aggiornare il UI in onPostExecute()

Esempio

Public class MyAsyncTask extends AsyncTask 
{ 

private Context context; 

public MyAsyncTask(Context context) { // can take other params if needed 
    this.context = context; 
} 

// Add your AsyncTask methods and logic 
//you can use your context variable in onPostExecute() to manipulate activity UI 
}` 

quindi chiamare nel vostro MainActivity

MyAsyncTask myTask = new MyAsyncTask(this); //can pass other variables as needed 
myTask.execute(); 
+0

grazie per la tua risposta mi piace, il problema è che runOnUIThread() non può essere eseguito se è un file indipendente, dovrò usarlo come classe interna, che non voglio perché userò lo stesso classe per 3 attività, e non ho intenzione di mettere l'intero pezzo di codice di AsyncTask in ogni attività – Alex

+0

Non è necessario utilizzare una classe interna. Passa un riferimento all'attività come parametro nel costruttore (come quello che sta descrivendo codeMagic). Quindi usa il riferimento all'attività per chiamare il metodo runOnUIThread() – Sababado

+1

Grazie a questo ha funzionato con onPostExecute()! – Alex

2

Credo nella maggior parte dei tutorial che raccolgono tutto ciò che è più facile da capire/leggere, non quello che è in realtà il migliore.

Con una classe interna, si mantengono disponibili le variabili dell'attività, che possono essere più semplici.

In generale, dovresti incapsulare il più possibile, anche i tuoi AsyncTasks, in modo da poterli riutilizzare da qualsiasi altro punto del tuo codice.

+0

sì, questo è il motivo per cui vorrei creare un file indipendente per questo, così posso usarlo non solo per uno scopo ma anche per più scopi – Alex

2

Sì È possibile creare AsyncTask class nel numero MainActivity.java.

public class CategoryListScreen extends Activity { 


    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
    new loadcategory().execute(); 
} 
class loadcategory extends AsyncTask<Void, Void, Void> { 

@Override 
     protected Void doInBackground(Void... params) { } 

protected void onPostExecute(Void param) { } 
    } // AsyncTask over 
}//main class over 
+0

il fatto è che non voglio usarlo come una classe interiore. Voglio usarlo come classe separata. – Alex

4

In generale abbiamo collocare AsyncTask in stessa classe per renderlo più chiaro che è usato da solo la stessa attività.

Se si desidera che AsyncTask Tobe riutilizzato da più di un'attività che, si può semplicemente creare una classe indipendente e passare i parametri dall'attività dai costruttori

È possibile creare interfaccia nel AsyncTask per inviare risposta da AsyncTask a la tua attività come di seguito e ti chiamo metodo lister quando richiesto.L'ho chiamato onPostExecute():

public class DeckDownloader extends AsyncTask<Void, Void, String> { 

    OnDownloadUpdateListener listener; 

    public interface OnDownloadUpdateListener { 
     public void OnDownloadDeckFinish(String Response);  
    } 


    public DeckDownloader(Context ctx, OnDownloadUpdateListener listener) { 
     mContext = ctx; 
     this.listener = listener; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 
     String str = "downloading"; 
     //your async code goes here 
     return str; 
    } 

    @Override 
    protected void onPreExecute() { 
      super.onPreExecute(); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
      if(listener != null) { 
       listener.OnDownloadDeckProgress(result); 
      } 
    } 
} 

E la classe di attività, è necessario attuare tale ascoltatore e scrivere il codice per aggiornare TextView in quel metodo di implementazione:

public class myActivity extends Activity{ 
      private DeckDownloader.OnDownloadUpdateListener downloadListener; 
      TextView txtAsyncResponse; 

      @Override 
      public void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       txtAsyncResponse = (TextView) findViewById(R.id.txtAsyncResponse); 


      downloadListener = new DeckDownloader.OnDownloadUpdateListener() { 
       @Override 
       public void OnDownloadDeckFinish(String Response) { 
        txtAsyncResponse.setText(Response); 
       } 
      }; 
    } 

E si può scrivere qui sotto code per iniziare AsyncTask nella vostra attività ogni volta richiesto come evento click del pulsante oppure

DeckDownloader mTask = new DeckDownloader(this.getApplicationContext(), downloadListener); 
mTask.execute(); 

Questo può essere il thindg che vuoi!

+0

e come posso modificare le visualizzazioni? Non riesco a eseguire runOnUIThread() se è una classe indipendente. – Alex

+0

perché stai usando runOnUIThread? qual è il tuo requisito? –

+1

Ho letto il tuo commento in questione è che qualcosa che devi modificare il contenuto della vista testo è in attività del chiamante dopo aver completato AsyncTask? La mia comprensione è corretta? –

Problemi correlati