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