Android 如何完全杀死/删除/删除/停止 AsyncTask

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10882543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:19:41  来源:igfitidea点击:

How to completely kill/remove/delete/stop an AsyncTask

androidandroid-asynctask

提问by Adam Varhegyi

I made an app that downloads videos from our server. The issue is:

我制作了一个从我们的服务器下载视频的应用程序。问题是:

When i cancel the downloading i call:

当我取消下载时,我调用:

myAsyncTask.cancel(true)

I noticed, that myAsyncTaskdoesn't stops on calling cancel... my ProgressDialogstill goes up and its like jumping from status to status showing me that each time I cancel and start again an AsyncTaskby clicking the download button, a new AsyncTaskstarts... Each time I click download.. then cancel, then again download a separate AsyncTaskstarts.

我注意到,这myAsyncTask并没有停止调用取消......我的ProgressDialog仍然会上升,就像从一个状态跳到另一个状态显示我每次取消并AsyncTask通过单击下载按钮重新AsyncTask开始时,一个新的开始......每个时间我点击下载..然后取消,然后再次下载一个单独的AsyncTask开始。

Why is myAsynTask.cancle(true)not cancelling my task ? I don't want it anymore on the background. I just want to completely shut it down if I click cancel.

为什么myAsynTask.cancle(true)不取消我的任务?我不想再在后台使用它了。如果我点击取消,我只想完全关闭它。

How to do it ?

怎么做 ?

E D I T:

编辑:

Thanks to gtumca-MAC, and the others who helped me did it by:

感谢 gtumca-MAC,以及其他帮助我做到的人:

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

Thanks!!!

谢谢!!!

回答by MAC

AsyncTask does not cancel process on

AsyncTask 不会取消进程

myAsynTask.cancel(true) 

For that you have to stop it manually.

为此,您必须手动停止它。

for example you are downloading video in doInBackground(..)in while/for loop.

例如,您正在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;
     }

回答by Mohamed Hussien

Declare in your class

在你的课堂上声明

DownloadFileAsync downloadFile = new DownloadFileAsync();

then On Create

然后在创建

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

in Your Background ()

在你的背景 ()

if (isCancelled())
    break;

@Override
protected void onCancelled(){

}

and you can kill your AsyncTask by

你可以通过以下方式杀死你的 AsyncTask

downloadFile.cancel(true);

回答by Zelleriation

When you start a separate thread(AyncTask) it has to finish. You have to manually add a cancel statement to your code inside the AsyncTask.

当您启动一个单独的线程(AyncTask)时,它必须完成。您必须手动向 AsyncTask 内的代码添加取消语句。

A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

可以随时通过调用 cancel(boolean) 取消任务。调用此方法将导致后续调用 isCancelled() 返回 true。调用此方法后,将在 doInBackground(Object[]) 返回后调用 onCancelled(Object),而不是 onPostExecute(Object)。为了确保尽快取消任务,您应该始终定期从 doInBackground(Object[]) 中检查 isCancelled() 的返回值,如果可能的话(例如在循环中)。

Checkout more in the documentation: http://developer.android.com/reference/android/os/AsyncTask.html

在文档中查看更多信息:http: //developer.android.com/reference/android/os/AsyncTask.html

回答by Ahmad Arslan

I have been researching from the last 2 weeks and I don't get to know that how we kill the Async operation manually. Some developers use BREAK; while checking in for loop. But on my scenario I am not using the loop inside of background thread. But I have got to know how it woks its a stupid logic but works perfectly fine.

我从过去 2 周开始一直在研究,但我不知道我们如何手动终止异步操作。一些开发人员使用 BREAK;在检查 for 循环时。但在我的场景中,我没有使用后台线程内部的循环。但我必须知道它是如何工作的,这是一个愚蠢的逻辑,但工作得很好。

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

Instead of canceling and doing so much work on background thread turn off the wifi programmatically

与其取消并在后台线程上做这么多工作,不如以编程方式关闭 wifi

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

where do you want to kill the operation and turn on it where do you need that.

你想在哪里终止操作并在你需要的地方打开它。

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

What happens is your try block jumps in to the IOException killing the background tasks.

发生的情况是您的 try 块跳转到 IOException 杀死后台任务。

回答by Jawad Zeb

You better use vogella asyncTask library which have a lot of features like priority and canceling background task. And a great tutorial or using it is here

你最好使用 vogella asyncTask 库,它有很多功能,比如优先级和取消后台任务。一个很棒的教程或使用它在这里

回答by Victor Ruiz.

You can use this code. I am downloading a OTA file as follow:

您可以使用此代码。我正在下载 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;
        }

    }

So, If you want to cancel, just use this code:

因此,如果您想取消,只需使用以下代码:

 fDownload.cancel(true);

回答by BENN1TH

I have used with success inside an activity with TextView onclick ...

我在 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) {

        }

and in my onCreate() ...

在我的 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();

        }
    });

and my xml TextView element ...

和我的 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"/>