Android: Comment puis-je passer des paramètres à onPreExecute () d'AsyncTask?

116

J'utilise un AsyncTaskpour les opérations de chargement que j'ai implémentées en tant que classe interne.

Dans onPreExecute()je montre une boîte de dialogue de chargement dans laquelle je me cache à nouveau onPostExecute(). Mais pour certaines opérations de chargement, je sais à l'avance qu'elles se termineront très rapidement donc je ne veux pas afficher la boîte de dialogue de chargement.

Je voulais l'indiquer par un paramètre booléen auquel je pourrais passer onPreExecute()mais apparemment, pour une raison quelconque, onPreExecute()ne prend aucun paramètre.

La solution de contournement évidente serait probablement de créer un champ membre dans mon AsyncTask ou dans la classe externe que je devrais définir avant chaque opération de chargement, mais cela ne semble pas très élégant. Y a-t-il une meilleure manière de faire cela?

Steven Meliopoulos
la source

Réponses:

230

Vous pouvez remplacer le constructeur. Quelque chose comme:

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

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

    // doInBackground() et al.
}

Ensuite, lors de l'appel de la tâche, faites quelque chose comme:

new MyAsyncTask(true).execute(maybe_other_params);

Modifier: c'est plus utile que de créer des variables membres car cela simplifie l'appel de la tâche. Comparez le code ci-dessus avec:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Félix
la source
3
C'est exactement ce que j'ai fait maintenant. J'ai toujours besoin d'une variable membre mais dans AsyncTask et non dans la classe externe si c'est ce que vous voulez dire. Voici ce que j'ai fait: la classe privée MyAsyncTask étend AsyncTask <Void, Void, Void> {private boolean showLoading; public MyAsyncTask (booléen showLoading) {super (); this.showLoading = showLoading; // faire des trucs} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () et al. }
Steven Meliopoulos
1
Ouais, c'était à peu près l'idée :)
Felix
1
Vous n'avez pas vraiment besoin de super () dans le constructeur AsynkTask.
ostergaard
62

1) Pour moi, c'est le moyen le plus simple de passer des paramètres à une tâche asynchrone.

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

Déclarez et utilisez la tâche asynchrone comme ici

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) Passer des méthodes à async-task Afin d'éviter de coder plusieurs fois l'infrastructure async-Task (thread, messagenhandler, ...), vous pouvez envisager de passer les méthodes qui doivent être exécutées dans votre async-task en tant que paramètre. L'exemple suivant décrit cette approche. De plus, vous pourriez avoir besoin de sous-classer la tâche async pour transmettre les paramètres d'initialisation dans le constructeur.

 /* 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
la source
11

pourquoi, comment et quels paramètres sont passés à Asynctask <>, voir les détails ici . Je pense que c'est la meilleure explication.

La documentation Android de Google indique que:

Une tâche asynchrone est définie par 3 types génériques, appelés Params, Progress et Result, et 4 étapes, appelées onPreExecute, doInBackground, onProgressUpdate et onPostExecute.

Types génériques d'AsyncTask:

Les trois types utilisés par une tâche asynchrone sont les suivants:

Params, le type des paramètres envoyés à la tâche lors de l'exécution. Progression, le type des unités de progression publiées lors du calcul d'arrière-plan. Result, le type du résultat du calcul en arrière-plan. Tous les types ne sont pas toujours utilisés par une tâche asynchrone. Pour marquer un type comme inutilisé, utilisez simplement le type Void:

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

Vous pouvez en outre vous référer: http://developer.android.com/reference/android/os/AsyncTask.html

Ou vous pouvez clarifier le rôle d'AsyncTask en vous référant au blog de Sankar-Ganesh

Eh bien, la structure d'une classe AsyncTask typique est la suivante:

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

    protected void onPreExecute(){ 

    } 

Cette méthode est exécutée avant de démarrer le nouveau Thread. Il n'y a pas de valeurs d'entrée / sortie, alors initialisez simplement les variables ou tout ce que vous pensez devoir faire.

protected Z doInBackground(X...x){

}

La méthode la plus importante de la classe AsyncTask. Vous devez placer ici tout ce que vous voulez faire en arrière-plan, dans un fil différent du fil principal. Ici, nous avons comme valeur d'entrée un tableau d'objets du type «X» (voyez-vous dans l'en-tête? Nous avons «... étend AsyncTask» Ce sont les TYPES des paramètres d'entrée) et renvoie un objet du type «Z».

protected void onProgressUpdate (Y y) {

} Cette méthode est appelée à l'aide de la méthode publishProgress (y) et elle est généralement utilisée lorsque vous souhaitez afficher une progression ou des informations dans l'écran principal, comme une barre de progression montrant la progression de l'opération que vous effectuez en arrière-plan.

protected void onPostExecute (Z z) {

} Cette méthode est appelée une fois l'opération en arrière-plan effectuée. En tant que paramètre d'entrée, vous recevrez le paramètre de sortie de la méthode doInBackground.

Qu'en est-il des types X, Y et Z?

Comme vous pouvez le déduire de la structure ci-dessus:

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.

Comment appelle-t-on cette tâche à partir d'une classe extérieure? Juste avec les deux lignes suivantes:

MyTask myTask = new MyTask();

myTask.execute(x);

Où x est le paramètre d'entrée de type X.

Une fois que nous avons notre tâche en cours d'exécution, nous pouvons connaître son statut «de l'extérieur». Utilisation de la méthode «getStatus ()».

myTask.getStatus (); et nous pouvons recevoir le statut suivant:

RUNNING - Indique que la tâche est en cours d'exécution.

PENDING - Indique que la tâche n'a pas encore été exécutée.

FINISHED - Indique que onPostExecute (Z) est terminé.

Conseils sur l'utilisation d'AsyncTask

N'appelez pas les méthodes onPreExecute, doInBackground et onPostExecute manuellement. Ceci est fait automatiquement par le système.

Vous ne pouvez pas appeler une AsyncTask dans une autre AsyncTask ou Thread. L'appel de la méthode execute doit être effectué dans le thread d'interface utilisateur.

La méthode onPostExecute est exécutée dans le thread d'interface utilisateur (ici, vous pouvez appeler une autre AsyncTask!).

Les paramètres d'entrée de la tâche peuvent être un tableau d'objets, de cette façon vous pouvez mettre les objets et les types que vous voulez.

Naveed Jamali
la source
4

Vous pouvez passer le paramètre dans le constructeur de tâche ou lorsque vous appelez execute:

AsyncTask<Object, Void, MyTaskResult>

Le premier paramètre (Object) est passé dans doInBackground. Le troisième paramètre (MyTaskResult) est renvoyé par doInBackground. Vous pouvez les changer pour les types souhaités. Les trois points signifient que zéro ou plusieurs objets (ou un tableau d'entre eux) peuvent être passés comme argument (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);

        }
    }

}
l'amour en direct
la source