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

7 minutos de lectura

avatar de usuario
Steven Meliopoulos

yo uso un AsyncTask para operaciones de carga que implementé como una clase interna.

En onPreExecute() Muestro un cuadro de diálogo de carga que luego escondo de nuevo en 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 que podría pasar a onPreExecute() pero al parecer 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?

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 crear 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();

  • 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 { private boolean showLoading; public MyAsyncTask(boolean showLoading) { super(); this.showLoading = showLoading; // hacer cosas } protected void onPreExecute(){ if(showLoading){ // … } } // doInBackground() et al. }

    – Steven Meliopoulos

    20 de junio de 2010 a las 21:48

  • Sí, esa era más o menos la idea 🙂

    – Félix

    20 de junio de 2010 a las 22:10

  • En realidad, no necesita super() en el constructor AsynkTask.

    – ostergaard

    11 de agosto de 2013 a las 4:41

avatar de usuario
Carlos

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

// 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 de la tarea asíncrona (subproceso, controlador de mensajes, …) varias veces, puede considerar pasar los métodos que deben ejecutarse en su tarea asíncrona como un parámetro. El siguiente ejemplo describe este enfoque. Además, es posible que tenga la necesidad de subclasificar la tarea asíncrona para pasar 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;
        }
    });     
}

avatar de usuario
Naveed Jamali

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 asíncrona se define por 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 asíncrona son los siguientes:

Params, el tipo de los parámetros enviados a la tarea tras la ejecución. Progreso, el tipo de unidades de progreso publicadas durante el cálculo de fondo. Resultado, el tipo del resultado del cálculo de fondo. No todos los tipos se usan siempre en una tarea asincrónica. Para marcar un tipo como no usado, 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 AsyncTask típica es así:

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 en la clase AsyncTask. Tienes que colocar aquí todo lo 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”.

vacío protegido enProgressUpdate(Y y){

} Este método se llama usando el métodopublishProgress(y) y generalmente se usa cuando desea mostrar cualquier progreso o información en la pantalla principal, como una barra de progreso que muestra el progreso de la operación que está realizando en segundo plano.

vacío protegido en PostExecute (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 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 una clase externa? 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 conocer su estado desde “afuera”. Utilizando el método “getStatus()”.

miTarea.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.

FINALIZADO: 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 del método de ejecución 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.

avatar de usuario
vive el amor

Puede pasar el parámetro en el constructor de tareas o cuando llama a ejecutar:

AsyncTask<Object, Void, MyTaskResult>

El primer parámetro (Objeto) se pasa en doInBackground. El tercer parámetro (MyTaskResult) lo devuelve doInBackground. Puede cambiarlos por 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);

        }
    }

}

¿Ha sido útil esta solución?