web-dev-qa-db-fra.com

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

J'utilise un AsyncTask pour charger les opérations que j'ai implémentées en tant que classe interne.

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

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

La solution é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?

111
Steven Meliopoulos

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, lorsque vous appelez la tâche, procédez comme suit:

new MyAsyncTask(true).execute(maybe_other_params);

Edit: Ceci est plus utile que la création de 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();
224
Felix

1) Pour moi, c'est le moyen le plus simple de passer des paramètres à la tâche asynchrone est comme ça

// 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 l'infrastructure async-Task (thread, gestionnaire de messages, ...), vous pourriez envisager de transmettre les méthodes qui devraient être exécutées dans votre async. -task en tant que paramètre. L'exemple suivant décrit cette approche. En outre, vous devrez peut-être sous-classer la tâche asynchrone 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;
        }
    });     
}
59
Karl

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

La documentation de Google Android indique que:

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

Types génériques de 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 son exécution. Progress, le type des unités de progression publiées lors du calcul en arrière-plan. Résultat, 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 étant inutilisé, utilisez simplement le type Void:

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

Vous pouvez également 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

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 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. Nous avons ici 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 retourne un objet du type "Z".

void protected onProgressUpdate (Y y) {

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

void protégé onPostExecute (Z z) {

} Cette méthode est appelée une fois l'opération en arrière-plan terminé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 appelons-nous cette tâche depuis 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 du type X.

Une fois que notre tâche est en cours, nous pouvons connaître son statut "de l’extérieur". Utilisation de la méthode “getStatus ()”.

ma tâche.getStatus (); et nous pouvons recevoir le statut suivant:

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

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

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

Conseils sur l'utilisation de 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 un 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 (vous pouvez ici appeler une autre AsyncTask!).

Les paramètres d’entrée de la tâche peuvent être un tableau d’objets, vous permettant ainsi de définir les objets et les types souhaités.

10
Naveed Jamali

Vous pouvez soit transmettre le paramètre dans le constructeur de la tâche ou, lorsque vous appelez, exécuter:

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 que vous voulez. Les trois points signifient que zéro ou plusieurs objets (ou un tableau d'entre eux) peuvent être passés en tant qu'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);

        }
    }

}
2
live-love