2013-03-18 8 views
11

Ho giocato con vari esempi cercando di familiarizzare con AsyncTask. Finora tutti gli esempi che ho visto hanno avuto l'AsyncTask incluso nel metodo onCreate dell'attività principale. Il che non mi piace molto, quindi volevo vedere quanto sarebbe difficile separarlo nella sua stessa classe. Finora ho questo:Sviluppo Android: Avere un AsyncTask in un file di classe separato

il attività principale

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.app.Activity; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.example.asynctaskactivity.ShowDialogAsyncTask; 

public class AsyncTaskActivity extends Activity { 

Button btn_start; 
ProgressBar progressBar; 
TextView txt_percentage; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btn_start = (Button) findViewById(R.id.btn_start); 
     progressBar = (ProgressBar) findViewById(R.id.progress); 
     txt_percentage= (TextView) findViewById(R.id.txt_percentage); 
     Log.v("onCreate","Attempt set up button OnClickListener"); 
     btn_start.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) { 
       btn_start.setEnabled(false); 
       new ShowDialogAsyncTask().execute(); 
      } 
     }); 

     Log.v("onCreate","Success!"); 
    } 
} 

la nuova separata classe AsyncTask

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.SystemClock; 
import android.util.Log; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{ 
int progress_status; 

@Override 
    protected void onPreExecute() { 
    // update the UI immediately after the task is executed 
    Log.v("onPreExecute","1"); 
    super.onPreExecute(); 
    Log.v("onPreExecute","2"); 
    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPreExecute()", Toast.LENGTH_SHORT).show(); 
    progress_status = 0; 
    Log.v("onPreExecute","3"); 
    txt_percentage.setText("downloading 0%"); 
    Log.v("onPreExecute","4"); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     Log.v("doInBackground","1"); 
     while(progress_status<100){ 

      progress_status += 2; 

      publishProgress(progress_status); 
      SystemClock.sleep(300); 

     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
    super.onProgressUpdate(values); 

    progressBar.setProgress(values[0]); 
    txt_percentage.setText("downloading " +values[0]+"%"); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 

    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPostExecute()", Toast.LENGTH_SHORT).show(); 

    txt_percentage.setText("download complete"); 
    btn_start.setEnabled(true); 
    } 
} 

In origine questo era tutto nell'attività principale, da cui il menzioni al elementi che l'asynctask dovrebbe in teoria aggiornare. Ovviamente al momento questo sta causando errori di runtime, che poi mi hanno fatto pensare. Come posso avere il file separato, ma continuo ad aggiornare il thread dell'interfaccia utente.

Scusa se questa è una domanda stupida, piuttosto nuova per lo sviluppo Android e thread in background in particolare.

+0

Sembra molto simile a questo http: // StackOverflow.it/questions/6119305/android-how-to-run-asynctask-from-different-class-file – user2070018

+1

Come sidenote, non è necessario chiamare i metodi super in un 'AsyncTask', non fanno nulla. – nhaarman

+0

Qual è il punto in loro in realtà, li ho notati in molti esempi di asynctasks che stavo guardando e non riuscivo a capire il loro scopo. – cosmicsafari

risposta

17

Come posso avere il file separato ma continuo ad aggiornare il thread dell'interfaccia utente.

Okey. Quindi all'inizio sai che il vantaggio principale di AsyncTask aggiunto in Attività come classe interna è che hai accesso diretto a tutti gli elementi dell'interfaccia utente e rende possibili gli aggiornamenti dell'interfaccia utente piuttosto "leggeri".

Ma se avete deciso di fare AsyncTask separato dalla attività (che hanno anche alcuni vantaggi eq codice è più pulito e la logica app è separata dalla comparsa) di classe è possibile:

  • È possibile passare elementi dell'interfaccia utente tramite costruttore della classe
  • È possibile creare vari setter
  • È possibile creare un'interfaccia che includerà i callback. Guarda Android AsyncTask sending Callbacks to UI

Questo è tutto ciò di cui hai bisogno credo.

8

Aggiungere un'interfaccia di richiamata e consentire all'implementazione di Activity.

public interface MyAsyncTaskCallback{ 
    public void onAsyncTaskComplete(); 
} 

Nella postExecute:

myAsyncTaskCallback.onAsyncTaskComplete(); 

Nel costruttore del vostro AsyncTask si poteva passare l'istanza di MyAsyncTaskCallback (vostra Activity).

1

Il modo migliore per gestirlo è tramite un gestore. Istanziare uno nell'attività e sovrascrivere il metodo handleMessage(). Quando crei la classe ShowDialogAsyncTask, passa il gestore e mantieni un riferimento ad esso. Su postExecute puoi costruire un messaggio e inviarlo tramite il metodo handler sendMessage(). Una risposta permeabile menzionata usando un'interfaccia e un paradigma di callback. Ciò funzionerà, tuttavia, esiste la possibilità che l'attività possa essere distrutta e non sia presente quando viene eseguito il metodo postExecute, pertanto è necessario verificarlo.

Problemi correlati