onprogressupdate - Cómo matar/eliminar/eliminar/detener completamente una AsyncTask en Android
oncancelled asynctask android (7)
AsyncTask no cancela el proceso en
myAsynTask.cancel(true)
Para eso debes detenerlo manualmente.
por ejemplo, está descargando video en doInBackground(..)
en while / for loop.
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;
}
Creé una aplicación que descarga videos de nuestro servidor. El problema es:
Cuando cancele la descarga, llamo a:
myAsyncTask.cancel(true)
Me di cuenta de que myAsyncTask
no se detiene al llamar cancelar ... mi ProgressDialog
sigue subiendo y es como pasar del estado al estado que me muestra que cada vez que cancelo y comienzo de nuevo una AsyncTask
haciendo clic en el botón de descarga, comienza una nueva AsyncTask
... Cada vez que hago clic en descargar ... luego lo cancelo, luego nuevamente descargo un AsyncTask
separado.
¿Por qué myAsynTask.cancle(true)
no cancela mi tarea? No lo quiero más en el fondo. Solo quiero apagarlo por completo si hago clic en cancelar.
Cómo hacerlo ?
EDITAR:
Gracias a gtumca-MAC, y los otros que me ayudaron lo hicieron de la siguiente manera:
while (((count = input.read(data)) != -1) && (this.isCancelled()==false))
{
total += count;
publishProgress((int) (total * 100 / lenghtOfFile));
output.write(data, 0, count);
}
¡¡¡Gracias!!!
Cuando comienzas un hilo por separado (AyncTask) tiene que terminar. Debe agregar manualmente una declaración de cancelación a su código dentro de AsyncTask.
Una tarea puede cancelarse en cualquier momento invocando cancelar (booleano). La invocación de este método provocará que las llamadas posteriores a isCancelled () devuelvan verdadero. Después de invocar este método, onCancelled (Object), en lugar de onPostExecute (Object) se invocará después de que doInBackground (Object []) regrese. Para garantizar que una tarea se cancele lo más rápido posible, siempre debe verificar el valor de retorno de isCancelled () periódicamente desde doInBackground (Object []), si es posible (dentro de un bucle, por ejemplo).
Consulte más en la documentación: http://developer.android.com/reference/android/os/AsyncTask.html
Declara en tu clase
DownloadFileAsync downloadFile = new DownloadFileAsync();
luego en Crear
DownloadFileAsync downloadFile = new DownloadFileAsync();
downloadFile.execute(url);
en tu fondo ()
if (isCancelled())
break;
@Override
protected void onCancelled(){
}
y puedes matar tu AsyncTask por
downloadFile.cancel(true);
Es mejor utilizar la biblioteca vogella asyncTask, que tiene muchas funciones como prioridad y cancelación de tareas en segundo plano. Y un gran tutorial o usarlo está here
He estado investigando en las últimas 2 semanas y no conozco cómo matamos manualmente la operación Async. Algunos desarrolladores usan BREAK; mientras se registra para el bucle. Pero en mi caso, no estoy usando el bucle dentro del hilo de fondo. Pero tengo que saber cómo funciona una lógica estúpida, pero funciona perfectamente bien.
downloadFile.cancel(true); //This code wont work in any case.
En lugar de cancelar y hacer tanto trabajo en el hilo de fondo apaga el wifi programáticamente
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(false);
¿Dónde quieres matar la operación y encenderla donde lo necesites?
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(true);
Lo que sucede es que tu bloque try salta a la IOException matando las tareas en segundo plano.
He utilizado con éxito dentro de una actividad con 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) {
}
y en mi 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();
}
});
y mi elemento 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"/>
Puedes usar este código Estoy descargando un archivo OTA de la siguiente manera:
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;
}
}
Por lo tanto, si desea cancelar, simplemente use este código:
fDownload.cancel(true);