Android: come posso passare parametri a onPreExecute () di AsyncTask?


116

Uso un AsyncTaskper le operazioni di caricamento che ho implementato come classe interna.

In onPreExecute()mostro una finestra di dialogo di caricamento in cui poi nascondo di nuovo onPostExecute(). Ma per alcune delle operazioni di caricamento so in anticipo che finiranno molto rapidamente, quindi non voglio visualizzare la finestra di dialogo di caricamento.

Volevo indicarlo con un parametro booleano a cui potrei passare onPreExecute()ma a quanto pare per qualche motivo onPreExecute()non accetta alcun parametro.

L'ovvia soluzione alternativa sarebbe probabilmente creare un campo membro nel mio AsyncTask o nella classe esterna che dovrei impostare prima di ogni operazione di caricamento, ma non sembra molto elegante. C'è un modo migliore per farlo?

Risposte:


231

È possibile sovrascrivere il costruttore. Qualcosa di simile a:

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

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

    // doInBackground() et al.
}

Quindi, quando chiami l'attività, fai qualcosa come:

new MyAsyncTask(true).execute(maybe_other_params);

Modifica: è più utile della creazione di variabili membro perché semplifica la chiamata dell'attività. Confronta il codice sopra con:

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

3
Questo è esattamente quello che ho fatto ora. Ho ancora bisogno di una variabile membro ma nell'AsyncTask e non nella classe esterna se è questo che intendi. Questo è quello che ho fatto: private class MyAsyncTask estende AsyncTask <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (boolean showLoading) {super (); this.showLoading = showLoading; // fai cose} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos

1
Sì, questa era più o meno l'idea :)
Felix,

1
In realtà non hai bisogno di super () nel costruttore AsynkTask.
ostergaard

62

1) Per me questo è il modo più semplice per passare i parametri all'attività asincrona è così

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

Dichiara e usa l'attività asincrona come qui

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) Passaggio di metodi all'attività asincrona Per evitare di codificare l'infrastruttura dell'attività asincrona (thread, messagenhandler, ...) più volte si potrebbe considerare di passare i metodi che dovrebbero essere eseguiti nella propria attività asincrona come parametro. L'esempio seguente delinea questo approccio. Inoltre potrebbe essere necessario creare una sottoclasse dell'attività asincrona per passare i parametri di inizializzazione nel costruttore.

 /* 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;
        }
    });     
}

11

perché, come e quali parametri vengono passati ad Asynctask <>, vedere i dettagli qui . Penso che sia la migliore spiegazione.

La documentazione Android di Google afferma che:

Un'attività asincrona è definita da 3 tipi generici, chiamati Params, Progress e Result, e 4 passaggi, chiamati onPreExecute, doInBackground, onProgressUpdate e onPostExecute.

Tipi generici di AsyncTask:

I tre tipi utilizzati da un'attività asincrona sono i seguenti:

Params, il tipo di parametri inviati all'attività al momento dell'esecuzione. Avanzamento, il tipo di unità di avanzamento pubblicate durante il calcolo in background. Risultato, il tipo di risultato del calcolo in background. Non tutti i tipi vengono sempre utilizzati da un'attività asincrona. Per contrassegnare un tipo come non utilizzato, usa semplicemente il tipo Void:

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

Puoi ulteriormente fare riferimento: http://developer.android.com/reference/android/os/AsyncTask.html

Oppure puoi chiarire qual è il ruolo di AsyncTask facendo riferimento al blog di Sankar-Ganesh

Bene La struttura di una tipica classe AsyncTask è simile a:

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

    protected void onPreExecute(){ 

    } 

Questo metodo viene eseguito prima di avviare il nuovo thread. Non ci sono valori di input / output, quindi inizializza semplicemente le variabili o qualsiasi altra cosa pensi di dover fare.

protected Z doInBackground(X...x){

}

Il metodo più importante nella classe AsyncTask. Devi mettere qui tutte le cose che vuoi fare in background, in un thread diverso da quello principale. Qui abbiamo come valore di input un array di oggetti del tipo "X" (Vedi nell'intestazione? Abbiamo "... extends AsyncTask" Questi sono i TIPI dei parametri di input) e restituisce un oggetto del tipo “Z”.

protected void onProgressUpdate (Y y) {

} Questo metodo viene chiamato utilizzando il metodo publishProgress (y) e di solito viene utilizzato quando si desidera mostrare qualsiasi progresso o informazione nella schermata principale, come una barra di avanzamento che mostra lo stato di avanzamento dell'operazione che si sta eseguendo in background.

protected void onPostExecute (Z z) {

} Questo metodo viene chiamato al termine dell'operazione in background. Come parametro di input riceverai il parametro di output del metodo doInBackground.

E i tipi X, Y e Z?

Come puoi dedurre dalla struttura sopra:

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.

Come chiamiamo questo compito da una classe esterna? Solo con le seguenti due righe:

MyTask myTask = new MyTask();

myTask.execute(x);

Dove x è il parametro di input del tipo X.

Una volta che abbiamo il nostro compito in esecuzione, possiamo scoprire il suo stato da "fuori". Utilizzando il metodo "getStatus ()".

myTask.getStatus (); e possiamo ricevere il seguente stato:

IN ESECUZIONE: indica che l'attività è in esecuzione.

PENDING - Indica che l'attività non è stata ancora eseguita.

FINISHED - Indica che onPostExecute (Z) è terminato.

Suggerimenti sull'utilizzo di AsyncTask

Non chiamare manualmente i metodi onPreExecute, doInBackground e onPostExecute. Questa operazione viene eseguita automaticamente dal sistema.

Non è possibile chiamare un AsyncTask all'interno di un altro AsyncTask o Thread. La chiamata del metodo execute deve essere eseguita nel thread dell'interfaccia utente.

Il metodo onPostExecute viene eseguito nel thread dell'interfaccia utente (qui puoi chiamare un altro AsyncTask!).

I parametri di input dell'attività possono essere un array di oggetti, in questo modo puoi inserire qualsiasi oggetto e tipo desideri.


4

È possibile passare il parametro nel costruttore dell'attività o quando si chiama execute:

AsyncTask<Object, Void, MyTaskResult>

Il primo parametro (Object) viene passato in doInBackground. Il terzo parametro (MyTaskResult) viene restituito da doInBackground. Puoi cambiarli nei tipi che desideri. I tre punti indicano che zero o più oggetti (o un array di essi) possono essere passati come argomenti.

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

        }
    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.