61 votes

Android: Annuler la tâche asynchrone

J'utilise un async tâche de charger une image et obtenir certains résultats.

Pendant le chargement de l'image, je vois une boîte de dialogue de progression, écrit en onPreExecute() la méthode comme ceci:

    protected void onPreExecute() { 
         uploadingDialog = new ProgressDialog(MyActivity.this); 
         uploadingDialog.setMessage("uploading"); 
         uploadingDialog.setCancelable(true);
         uploadingDialog.show();
    }

Ok quand j'appuie sur le bouton de retour, évidemment, la boîte de dialogue disparaît en raison de la setCancelable(true).

Mais (évidemment), le async tâche ne s'arrête pas.

Alors, comment puis-je résoudre ce problème? Je veux annuler les deux dialogue et async task lorsque j'appuie sur le bouton retour. Des idées?

EDIT: TROUVÉ LA SOLUTION. VOIR MA RÉPONSE CI-DESSOUS.

109voto

Paresh Mayani Points 48123

De SDK:

Annulation d'une tâche

Une tâche peut être annulé à tout moment en appelant annuler(boolean). L'invocation de cette méthode provoque des appels ultérieurs à isCancelled() retourner la valeur true.

Après l'invocation de cette méthode, onCancelled(Objet), au lieu de onPostExecute(Objet) sera invoquée après doInBackground(Object[]) renvoie la.

Pour s'assurer qu'une tâche est annulée aussi rapidement que possible, vous devriez toujours vérifier la valeur de retour de isCancelled() afin de doInBackground(Object[]), si possible (dans une boucle par exemple).

Si votre code est bon pour boîte de dialogue de l'écouteur:

 uploadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
          public void onCancel(DialogInterface dialog) {
              myTask.cancel(true);
              //finish();
          }
    });

Maintenant, comme je l'ai mentionné précédemment, à partir de SDK, vous devez vérifier si la tâche est annulée ou pas, pour que vous devez vérifier isCancelled() à l'intérieur de la onPreExecute() la méthode.

Par exemple:

if (isCancelled()) 
    break;
else
{
   // do your work here
}

31voto

mole363 Points 438

TROUVEZ LA SOLUTION : J'ai ajouté un écouteur d'action avant de téléverserDialog.show () comme ceci:

     uploadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
          public void onCancel(DialogInterface dialog) {
              myTask.cancel(true);
              //finish();
          }
    });
 

Ainsi, lorsque j'appuie sur le bouton Précédent, l'OnCancelListener ci-dessus annule le dialogue et la tâche. Vous pouvez également ajouter finish () si vous souhaitez terminer l’activité complète au dos. N'oubliez pas de déclarer votre tâche asynchrone comme une variable comme celle-ci:

     MyAsyncTask myTask=null;
 

et exécutez votre tâche asynchrone comme ceci:

     myTask = new MyAsyncTask();
    myTask.execute();
 

11voto

odiggity Points 659

J'ai passé un certain temps à comprendre cela, tout ce que je voulais, c'était un exemple simple de la façon de le faire. J'ai donc pensé poster ce que j'ai fait. Il s'agit d'un code qui met à jour une bibliothèque et comporte une boîte de dialogue de progression indiquant le nombre de livres mis à jour et annulant lorsqu'un utilisateur ferme la boîte de dialogue:

 private class UpdateLibrary extends AsyncTask<Void, Integer, Boolean>{
    private ProgressDialog dialog = new ProgressDialog(Library.this);
    private int total = Library.instance.appState.getAvailableText().length;
    private int count = 0;

    //Used as handler to cancel task if back button is pressed
    private AsyncTask<Void, Integer, Boolean> updateTask = null;

    @Override
    protected void onPreExecute(){
        updateTask = this;
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setOnDismissListener(new OnDismissListener() {               
            @Override
            public void onDismiss(DialogInterface dialog) {
                updateTask.cancel(true);
            }
        });
        dialog.setMessage("Updating Library...");
        dialog.setMax(total);
        dialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... arg0) {
            for (int i = 0; i < appState.getAvailableText().length;i++){
                if(isCancelled()){
                    break;
                }
                //Do your updating stuff here
            }
        }

    @Override
    protected void onProgressUpdate(Integer... progress){
        count += progress[0];
        dialog.setProgress(count);
    }

    @Override
    protected void onPostExecute(Boolean finished){
        dialog.dismiss();
        if (finished)
            DialogHelper.showMessage(Str.TEXT_UPDATELIBRARY, Str.TEXT_UPDATECOMPLETED, Library.instance);
        else 
            DialogHelper.showMessage(Str.TEXT_UPDATELIBRARY,Str.TEXT_NOUPDATE , Library.instance);
    }
}
 

9voto

jkhouw1 Points 4856

créer des variables de membre dans votre activité comme

 YourAsyncTask mTask;
Dialog mDialog;
 

utilisez-les pour votre dialogue et votre tâche;

dans onPause () simplement appeler

 if(mTask!=null) mTask.cancel(); 
if(mDialog!=null) mDialog.dismiss();
 

2voto

advantej Points 6414

Vous pouvez simplement demander une annulation mais pas vraiment y mettre fin. Voir cette réponse .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X