Android: ¿Cómo puedo pasar parámetros a onPreExecute () de AsyncTask?

116

Utilizo un AsyncTaskpara cargar operaciones que implementé como una clase interna.

En onPreExecute()muestro un cuadro de diálogo de carga en el que luego me escondo nuevamente onPostExecute(). Pero para algunas de las operaciones de carga, sé de antemano que terminarán muy rápido, por lo que no quiero mostrar el cuadro de diálogo de carga.

Quería indicar esto mediante un parámetro booleano al que podría pasar, onPreExecute()pero aparentemente, por alguna razón 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?

Steven Meliopoulos
fuente

Respuestas:

231

Puede anular el constructor. Algo como:

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

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

    // doInBackground() et al.
}

Luego, al llamar a la tarea, haga algo como:

new MyAsyncTask(true).execute(maybe_other_params);

Editar: esto es más útil que la creación de variables miembro porque simplifica la invocación de la tarea. Compare el código anterior con:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Felix
fuente
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: la clase privada MyAsyncTask extiende AsyncTask <Void, Void, Void> {showLoading booleano privado; public MyAsyncTask (showLoading booleano) {super (); this.showLoading = showLoading; // hacer cosas} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos
1
Sí, esa era prácticamente la idea :)
Felix
1
En realidad, no necesita super () en el constructor AsynkTask.
ostergaard
62

1) Para mí, esa es la forma más sencilla de pasar parámetros a una tarea asíncrona.

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

Declare y use 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) Pasar métodos a async-task Para evitar codificar la infraestructura async-Task (hilo, messagenhandler, ...) varias veces, podría considerar pasar los métodos que deben ejecutarse en su async-task como parámetro. El siguiente ejemplo describe este enfoque. Además, es posible que tenga la necesidad de crear una subclase de la tarea asíncrona 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;
        }
    });     
}
Karl
fuente
11

por qué, cómo y qué parámetros se pasan a Asynctask <>, consulte los detalles aquí . Creo que es la mejor explicación.

La documentación de Android de Google dice que:

Una tarea asincrónica se define mediante 3 tipos genéricos, llamados Params, Progress y Result, y 4 pasos, llamados onPreExecute, doInBackground, onProgressUpdate y onPostExecute.

Tipos genéricos de AsyncTask:

Los tres tipos utilizados por una tarea asincrónica son los siguientes:

Params, el tipo de parámetros que se envían a la tarea al ejecutarse. Progreso, el tipo de unidades de progreso publicadas durante el cálculo de fondo. Resultado, el tipo de resultado del cálculo de fondo. No todos los tipos se utilizan siempre en una tarea asincrónica. Para marcar un tipo como no utilizado, simplemente use el tipo Void:

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

Puede consultar más: http://developer.android.com/reference/android/os/AsyncTask.html

O puede aclarar cuál es el papel de AsyncTask consultando el Blog de Sankar-Ganesh

Bueno, la estructura de una clase típica AsyncTask es la siguiente:

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

    protected void onPreExecute(){ 

    } 

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

protected Z doInBackground(X...x){

}

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

protected void onProgressUpdate (Y y) {

} Este método se llama usando el método publishProgress (y) y generalmente se usa cuando quieres mostrar algún progreso o información en la pantalla principal, como una barra de progreso que muestra el progreso de la operación que estás haciendo en segundo plano.

protected void onPostExecute (Z z) {

} Este método se llama después de que se realiza la operación en segundo plano. 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 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 una clase externa? Solo 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 desde “afuera”. 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.

FINISHED: indica que onPostExecute (Z) ha finalizado.

Sugerencias sobre el uso de AsyncTask

No llame a los métodos onPreExecute, doInBackground y onPostExecute manualmente. Esto lo hace automáticamente el sistema.

No puede llamar a una AsyncTask dentro de otra AsyncTask o Thread. La llamada al método execute debe realizarse en el subproceso de la interfaz de usuario.

El método onPostExecute se ejecuta en el subproceso de la interfaz de usuario (¡aquí puede llamar a otra 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.

Naveed Jamali
fuente
4

Puede pasar el parámetro en el constructor de la tarea o cuando llame a ejecutar:

AsyncTask<Object, Void, MyTaskResult>

El primer parámetro (Objeto) se pasa en doInBackground. El tercer parámetro (MyTaskResult) es devuelto por doInBackground. Puede cambiarlos a los tipos que desee. Los tres puntos significan que se pueden pasar cero o más objetos (o una matriz de ellos) 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);

        }
    }

}
vive el amor
fuente