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!!!
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;
}
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);
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
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.
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
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"/>
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);