web-dev-qa-db-fra.com

Comment complètement tuer/supprimer/supprimer/arrêter un AsyncTask dans Android

J'ai créé une application qui télécharge des vidéos de notre serveur ... Le problème est le suivant:

Quand j'annule le téléchargement, j'appelle:

myAsyncTask.cancel(true)

J'ai remarqué que myAsyncTask n'arrête pas en appelant annuler ... ma ProgressDialog monte toujours et c'est comme si je sautais d'un statut à l'autre en me montrant que chaque fois que j'annule et redémarre une AsyncTask en cliquant sur le bouton de téléchargement, une nouvelle AsyncTask commence ... Chaque fois que je clique sur télécharger .. puis annule, puis télécharge à nouveau une AsyncTask séparée commence.

Pourquoi myAsynTask.cancle(true) n'annule-il pas ma tâche? Je n'en veux plus sur le fond. Je veux juste l'éteindre complètement si je clique sur Annuler.

Comment faire ?

MODIFIER: 

Merci à gtumca-MAC et aux autres qui m'ont aidé à le faire en:

while (((count = input.read(data)) != -1) && (this.isCancelled()==false)) 
{
    total += count;
    publishProgress((int) (total * 100 / lenghtOfFile));
    output.write(data, 0, count);
}

Merci!!!

23
Adam Varhegyi

AsyncTask n'annule pas le processus sur

myAsynTask.cancel(true) 

Pour cela, vous devez l'arrêter manuellement.

par exemple, vous téléchargez une vidéo dans doInBackground(..) dans une boucle while/for.

protected Long doInBackground(URL... urls) {

         for (int i = 0; i < count; i++) {
          // you need to break your loop on particular condition here

             if(isCancelled())
                  break;             
         }
         return totalSize;
     }
52
MAC

Déclarer dans votre classe

DownloadFileAsync downloadFile = new DownloadFileAsync();

puis sur Create

DownloadFileAsync downloadFile = new DownloadFileAsync();
downloadFile.execute(url);

dans ton fond ()

if (isCancelled())
    break;

@Override
protected void onCancelled(){

}

et vous pouvez tuer votre AsyncTask par

downloadFile.cancel(true);
4
Mohamed Hussien

Lorsque vous démarrez un thread séparé (AyncTask), il doit se terminer. Vous devez ajouter manuellement une instruction d'annulation à votre code dans la tâche Async.

Une tâche peut être annulée à tout moment en appelant cancel (booléen). L'appel de cette méthode fera que les appels suivants à isCancelled () renverront true. Après avoir appelé cette méthode, onCancelled (Object), au lieu de onPostExecute (Object), sera appelé après le retour de doInBackground (Object []). Pour vous assurer qu'une tâche est annulée aussi rapidement que possible, vous devez toujours vérifier périodiquement la valeur de retour de isCancelled () depuis doInBackground (Object []), si possible (à l'intérieur d'une boucle, par exemple).

Commander plus dans la documentation: http://developer.Android.com/reference/Android/os/AsyncTask.html

1
Zelleriation

Je fais des recherches depuis 2 semaines et je ne comprends pas comment on élimine l'opération Async manuellement. Certains développeurs utilisent BREAK; tout en vérifiant la boucle. Mais sur mon scénario je n'utilise pas la boucle à l'intérieur du fil de fond. Mais je dois savoir comment ça se passe, c'est une logique stupide mais qui fonctionne parfaitement.

downloadFile.cancel(true);   //This code wont work in any case.

Au lieu d'annuler et de faire autant de travail sur le fil d'arrière-plan, désactivez le wifi par programmation

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(false);

où voulez-vous tuer l'opération et l'activer où en avez-vous besoin?.

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(true);

Qu'est-ce qui se passe est votre bloc try saute dans l'IOException tuer les tâches en arrière-plan.

0
Ahmad Arslan

Vous feriez mieux d'utiliser la bibliothèque vogella asyncTask qui comporte de nombreuses fonctionnalités telles que la priorité et l'annulation de la tâche en arrière-plan. Et un bon tutoriel ou l’utiliser est ici

0
Xar E Ahmer

J'ai utilisé avec succès une activité avec TextView onclick ...

        //inside the doInBackground() ...

        try {
        while (true) {
        System.out.println(new Date());

        //should be 1 * 1000 for second
        Thread.sleep(5 * 1000);
        if (isCancelled()) {
              return null;
        }
          }

        } catch (InterruptedException e) {

        }

et dans mon onCreate () ...

     //set Activity
     final SplashActivity sPlashScreen = this;

     //init my Async Task
     final RetrieveFeedTask syncDo = new RetrieveFeedTask();
     syncDo.execute();

     //init skip link
     skip_text = (TextView) findViewById(R.id.skip_text);
     skip_text.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //cancel Async
            syncDo.cancel(true);

            //goto/start another activity
            Intent intent = new Intent();
            intent.setClass(sPlashScreen, MainActivity.class);
            startActivity(intent);
            finish();

        }
    });

et mon élément xml TextView ...

   <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:id="@+id/skip_text"
        Android:layout_marginTop="20dp"
        Android:text="SKIP"
        Android:textColor="@color/colorAccent"/>
0
BENN1TH

Vous pouvez utiliser ce code. Je télécharge un fichier OTA comme suit: 

static class FirmwareDownload extends AsyncTask<String, String, String> {

        public String TAG = "Super LOG";
        public String file;
        int lenghtOfFile;
        long total;

        @Override
        protected String doInBackground(String... f_url) {
            try {
                int count;
                Utilies.getInternet();

                URL url = new URL(f_url[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
                lenghtOfFile = connection.getContentLength();
                mProgressBar.setMax(lenghtOfFile);
                InputStream input = new BufferedInputStream(url.openStream(), 8192);
                String fileName = f_url[0].substring(f_url[0].lastIndexOf("/"), f_url[0].length());
                File root = Environment.getExternalStorageDirectory();
                File dir = new File(root.getAbsolutePath() + fileName);

                Log.d(TAG, "trying to download in : " + dir);
                dir.getAbsolutePath();
                OutputStream output = new FileOutputStream(dir);
                byte data[] = new byte[1024];


                while ((count = input.read(data)) != -1) {

                    if (isCancelled())
                        break;

                    total += count;
                    mProgressBar.setProgress(Integer.parseInt("" + total));
                    Log.d("Downloading " + fileName + " : ", " " + (int) ((total * 100) / lenghtOfFile));
                    mPercentage.post(new Runnable() {
                        @Override
                        public void run() {
                            mPercentage.setText(total / (1024 * 1024) + " Mb / " + lenghtOfFile / (1024 * 1024) + " Mb");
                        }
                    });
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();

                //new InstallHelper().commandLine("mkdir data/data/ota");

                File fDest = new File("/data/data/ota/" + fileName);
                copyFile(dir, fDest);
                FirmwareInstaller fw = new FirmwareInstaller();
                fw.updateFirmware();

            } catch (Exception a) {
                System.out.println("Error trying donwloading firmware " + a);
                new InstallHelper().commandLine("rm -r  data/data/ota");
                dialog.dismiss();

            }
            return null;
        }

    }

Donc, si vous voulez annuler, utilisez simplement ce code:

 fDownload.cancel(true);
0
Victor Ruiz C.