2010-06-19 27 views
96

Utilizo un AsyncTask para las operaciones de carga que implementé como una clase interna.Android: ¿Cómo puedo pasar los parámetros a OnPreExecute() de AsyncTask?

En onPreExecute() muestro un cuadro de diálogo de carga que luego oculto de nuevo en onPostExecute(). Pero para algunas de las operaciones de carga sé de antemano que terminarán muy rápido, así que no quiero mostrar el cuadro de diálogo de carga.

Quería indicar esto mediante un parámetro booleano que podría pasar a onPreExecute() pero aparentemente por algún motivo onPreExecute() no toma ningún parámetro.

La solución obvia probablemente sería crear un campo miembro en mi AsyncTask o en la clase externa que tendría que configurar antes de cada operación de carga, pero eso no parece muy elegante. ¿Hay una mejor manera de hacer esto?

Respuesta

202

Puede anular el constructor. Algo así como:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> { 

    public MyAsyncTask(boolean showLoading) { 
     super(); 
     // do stuff 
    } 

    // doInBackground() et al. 
} 

Entonces, cuando se llama a la tarea, hacer algo como:

new MyAsyncTask(true).execute(maybe_other_params); 

Editar: esto es más útil que la creación de variables miembro, ya que simplifica la invocación de tareas. Comparar el código anterior con:

MyAsyncTask task = new MyAsyncTask(); 
task.showLoading = false; 
task.execute(); 
+3

Esto es exactamente lo que hice ahora. Todavía necesito una variable miembro pero en AsyncTask y no en la clase externa si eso es lo que quieres decir. Esto es lo que hice: clase privada MyAsyncTask extiende AsyncTask { private boolean showLoading; public MyAsyncTask (boolean showLoading) { super(); this.showLoading = showLoading; // hacer cosas } protected void OnPreExecute() {si (showLoading) {// ... }} // doInBackground() et al. } –

+1

Sí, esa fue más o menos la idea :) – Felix

+3

Esta es la respuesta correcta –

49

1) Para mí eso es lo más simples parámetros de manera que pasan a asíncrono tarea es como esto

// To call the async task do it like this 
Boolean[] myTaskParams = { true, true, true }; 
myAsyncTask = new myAsyncTask().execute(myTaskParams); 

declarar y utilizar la tarea asíncrona como aquí

private class myAsyncTask extends AsyncTask<Boolean, Void, Void> { 

    @Override 
    protected Void doInBackground(Boolean...pParams) 
    { 
     Boolean param1, param2, param3; 

     // 

      param1=pParams[0];  
      param2=pParams[1]; 
      param3=pParams[2];  
     .... 
}       

2) Pasando los métodos a async-task Para evitar codificar la infraestructura async-Task (thread, messagenhandler, ...) varias veces, puede considerar pasar los métodos que deberían ejecutarse en su async-task como parámetro. El siguiente ejemplo describe este enfoque. Además, puede tener la necesidad de subclase de la tarea asincrónica para pasar los parámetros de inicialización en el constructor.

/* Generic Async Task */ 
interface MyGenericMethod { 
    int execute(String param); 
} 

protected class testtask extends AsyncTask<MyGenericMethod, Void, Void> 
{ 
    public String mParam;       // member variable to parameterize the function 
    @Override 
    protected Void doInBackground(MyGenericMethod... params) { 
     // do something here 
     params[0].execute("Myparameter"); 
     return null; 
    }  
} 

// to start the asynctask do something like that 
public void startAsyncTask() 
{ 
    // 
    AsyncTask<MyGenericMethod, Void, Void> mytest = new testtask().execute(new MyGenericMethod() { 
     public int execute(String param) { 
      //body 
      return 1; 
     } 
    });  
} 
8

por qué, cómo y qué parámetros se pasan a AsyncTask <>, ver detalle here. Creo que es la mejor explicación.

Documentación Android de Google dice que:

Una tarea asíncrona se define por 3 tipos genéricos, llamado Parámetros, avance y de resultados, y 4 pasos, llamado OnPreExecute, doInBackground, onProgressUpdate y onPostExecute.

tipos genéricos de AsyncTask:

Los tres tipos utilizados por una tarea asíncrona son los siguientes:

Parámetros, el tipo de los parámetros enviados a la tarea en ejecución. Progreso, el tipo de unidades de progreso publicadas durante el cálculo en segundo plano. Resultado, el tipo de resultado del cálculo de fondo. No todos los tipos son siempre utilizados por una tarea asincrónica. Para marcar un tipo que sin usar, basta con utilizar el tipo Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... } 

puede hacer referencia más adelante: http://developer.android.com/reference/android/os/AsyncTask.html

o puede eliminar cuál es el papel de AsyncTask refiriendo Blog de Sankar-Ganesh

Bueno la estructura de una clase AsyncTask típica es como sigue:

private class MyTask extends AsyncTask<X, Y, Z> 

    protected void onPreExecute(){ 

    } 

se ejecuta este método antes de comenzar el nuevo hilo. No hay valores de entrada/salida, así que simplemente inicialice las variables o lo que sea que crea que necesita hacer.

protected Z doInBackground(X...x){ 

} 

El método más importante en la clase AsyncTask. Debe colocar aquí todas las cosas que desea hacer en segundo plano, en un hilo diferente del principal. Aquí tenemos como valor de entrada una matriz de objetos del tipo "X" (¿Ves en el encabezado? Tenemos "... extends AsyncTask" Estos son los TIPOS de los parámetros de entrada) y devuelve un objeto del tipo "Z".

protegida onProgressUpdate vacío (Y y) {

} Este método se llama mediante el publishProgress método (y) y por lo general se utiliza cuando se desea mostrar ningún progreso o información en la pantalla principal, como una barra de progreso que muestra el progreso de la operación que está haciendo en segundo plano.

protected void onPostExecute (Z z) {

} Este método se llama después de la operación en el fondo se hace. Como parámetro de entrada, recibirá el parámetro de salida del método doInBackground.

¿Qué pasa con los tipos X, Y y Z?

Como se puede deducir de la estructura anterior:

X – The type of the input variables value you want to set to the background process. This can be an array of objects. 

Y – The type of the objects you are going to enter in the onProgressUpdate method. 

Z – The type of the result from the operations you have done in the background process. 

¿Cómo llamamos a esta tarea desde un fuera de clase? Sólo con las siguientes dos líneas:

MyTask myTask = new MyTask(); 

myTask.execute(x); 

Donde x es el parámetro de entrada del tipo X.

Una vez que tenemos nuestra tarea en ejecución, podemos averiguar su estado de “fuera”. Usando el método "getStatus()".

myTask.getStatus(); y podemos recibir el siguiente estado:

EN EJECUCIÓN: indica que la tarea se está ejecutando.

PENDIENTE - Indica que la tarea aún no se ha ejecutado.

ACABADO - Indica que onPostExecute (Z) ha finalizado.

Consejos sobre el uso de AsyncTask

No llamar a los métodos OnPreExecute, doInBackground y onPostExecute manualmente. Esto es hecho automáticamente por el sistema.

No puede llamar a una AsyncTask dentro de otra AsyncTask o Thread. La llamada de la ejecución del método debe realizarse en el subproceso UI.

El método onPostExecute se ejecuta en el subproceso UI (aquí puede llamar a otro AsyncTask!).

Los parámetros de entrada de la tarea pueden ser una matriz de objetos, de esta manera puede colocar los objetos y tipos que desee.

0

Usted puede pasar el parámetro en el constructor tarea o cuando se llama a ejecutar:

AsyncTask<Object, Void, MyTaskResult> 

El primer parámetro (Objeto) se pasa en doInBackground. DoInBackground devuelve el tercer parámetro (MyTaskResult). Puede cambiarlos a los tipos que desee. Los tres puntos significan que cero o más objetos (o una matriz de ellos) se pueden pasar como argumento (s).

public class MyActivity extends AppCompatActivity { 

    TextView textView1; 
    TextView textView2; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main2);  
     textView1 = (TextView) findViewById(R.id.textView1); 
     textView2 = (TextView) findViewById(R.id.textView2); 

     String input1 = "test"; 
     boolean input2 = true; 
     int input3 = 100; 
     long input4 = 100000000; 

     new MyTask(input3, input4).execute(input1, input2); 
    } 

    private class MyTaskResult { 
     String text1; 
     String text2; 
    } 

    private class MyTask extends AsyncTask<Object, Void, MyTaskResult> { 
     private String val1; 
     private boolean val2; 
     private int val3; 
     private long val4; 


     public MyTask(int in3, long in4) { 
      this.val3 = in3; 
      this.val4 = in4; 

      // Do something ... 
     } 

     protected void onPreExecute() { 
      // Do something ... 
     } 

     @Override 
     protected MyTaskResult doInBackground(Object... params) { 
      MyTaskResult res = new MyTaskResult(); 
      val1 = (String) params[0]; 
      val2 = (boolean) params[1]; 

      //Do some lengthy operation  
      res.text1 = RunProc1(val1); 
      res.text2 = RunProc2(val2); 

      return res; 
     } 

     @Override 
     protected void onPostExecute(MyTaskResult res) { 
      textView1.setText(res.text1); 
      textView2.setText(res.text2); 

     } 
    } 

} 
Cuestiones relacionadas