Как полностью убить / удалить / удалить / остановить AsyncTask в Android
Я сделал приложение, которое загружает видео с нашего сервера. Вопрос заключается в следующем:
Когда я отменяю загрузку, я звоню:
myAsyncTask.cancel(true)
Я заметил, что myAsyncTask
не останавливается на звонке отменить... мой ProgressDialog
все еще идет вверх, и это похоже на переход из состояния в состояние, показывая мне, что каждый раз, когда я отменяю и начинаю снова AsyncTask
нажав на кнопку загрузки, новый AsyncTask
запускается... Каждый раз, когда я нажимаю "загрузить", затем отменять, а затем снова загружать отдельный AsyncTask
начинается.
Почему myAsynTask.cancle(true)
не отменяет мою задачу? Я больше не хочу этого на заднем плане. Я просто хочу полностью закрыть его, если я нажму "Отмена".
Как это сделать?
РЕДАКТИРОВАТЬ:
Благодаря gtumca-MAC и другим, кто помог мне, сделали это:
while (((count = input.read(data)) != -1) && (this.isCancelled()==false))
{
total += count;
publishProgress((int) (total * 100 / lenghtOfFile));
output.write(data, 0, count);
}
Спасибо!!!
7 ответов
AsyncTask не отменяет процесс на
myAsynTask.cancel(true)
Для этого вы должны остановить его вручную.
например, вы загружаете видео в doInBackground(..)
в то время как / для цикла.
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;
}
Объявите в своем классе
DownloadFileAsync downloadFile = new DownloadFileAsync();
затем при создании
DownloadFileAsync downloadFile = new DownloadFileAsync();
downloadFile.execute(url);
в твоем фоне ()
if (isCancelled())
break;
@Override
protected void onCancelled(){
}
и вы можете убить свой AsyncTask с помощью
downloadFile.cancel(true);
Когда вы запускаете отдельный поток (AyncTask), он должен закончиться. Вы должны вручную добавить оператор отмены в свой код внутри AsyncTask.
Задача может быть отменена в любое время, вызвав отмена (булево). Вызов этого метода приведет к тому, что последующие вызовы isCancelled() вернут true. После вызова этого метода onCancelled (Object) вместо onPostExecute(Object) будет вызываться после возврата doInBackground(Object[]). Чтобы отменить задачу как можно быстрее, всегда следует периодически проверять возвращаемое значение isCancelled() из doInBackground(Object[]), если это возможно (например, внутри цикла.)
Проверьте больше в документации: http://developer.android.com/reference/android/os/AsyncTask.html
Лучше использовать библиотеку vogella asyncTask, которая имеет множество функций, таких как приоритет и отмена фоновой задачи. И отличный учебник или использовать его здесь
Вы можете использовать этот код. Я загружаю OTA-файл следующим образом:
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;
}
}
Итак, если вы хотите отменить, просто используйте этот код:
fDownload.cancel(true);
Я исследовал последние 2 недели, и я не знаю, как мы убиваем асинхронную операцию вручную. Некоторые разработчики используют BREAK; во время проверки на петлю. Но в моем сценарии я не использую цикл внутри фонового потока. Но я должен знать, как это пробуждает его глупую логику, но прекрасно работает.
downloadFile.cancel(true); //This code wont work in any case.
Вместо того, чтобы отменить и сделать так много работы в фоновом потоке, отключите Wi-Fi программно
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(false);
где вы хотите убить операцию и включить ее, где вам это нужно.
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(true);
То, что происходит, это когда ваш блок try перепрыгивает с IOException, убивая фоновые задачи.
Я с успехом использовал в деятельности с 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) {
}
и в моем 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();
}
});
и мой элемент 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"/>