Android:取消异步任务

ste*_*osf 57 android asynchronous task back

我使用异步任务上传图像并获得一些结果.

在上传图像时,我看到一个进度对话框,用onPreExecute()方法编写,如下所示:

    protected void onPreExecute() { 
         uploadingDialog = new ProgressDialog(MyActivity.this); 
         uploadingDialog.setMessage("uploading"); 
         uploadingDialog.setCancelable(true);
         uploadingDialog.show();
    }
Run Code Online (Sandbox Code Playgroud)

好的,当我按下后退按钮时,显然对话框因setCancelable(true)而消失.

但(显然)异步任务不会停止.

那么我该如何解决这个问题呢?当我按下后退按钮时,我想取消对话和异步任务.有任何想法吗?

编辑:找到解决方案.请看下面我的答案.

Par*_*ani 102

来自SDK:

取消任务

可以通过调用cancel(boolean)随时取消任务.调用此方法将导致后续调用isCancelled()返回true.

调用此方法后,将在doInBackground(Object [])返回后调用onCancelled(Object)而不是onPostExecute(Object).

为确保尽快取消任务,应始终定期从doInBackground(Object [])检查isCancelled()的返回值,如果可能的话(例如在循环内).

所以你的代码适合对话框监听器:

uploadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
    public void onCancel(DialogInterface dialog) {
        myTask.cancel(true);
        //finish();
    }
});
Run Code Online (Sandbox Code Playgroud)

现在,正如我之前在SDK中提到的那样,您必须检查任务是否被取消,因为您必须在onPreExecute()方法中检查isCancelled().

例如:

if (isCancelled()) 
    break;
else
{
   // do your work here
}
Run Code Online (Sandbox Code Playgroud)

  • 是的我同意你的观点,但问题是我在doInBackground上没有使用循环.我只是使用一些命令通过ftp上传图像.所以我想知道,在发送图像之前检查任务是否被取消是否重要,就像你说的那样? (2认同)

ste*_*osf 31

发现解决方案:我在上传Digial.show()之前添加了一个动作监听器:

    uploadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
          public void onCancel(DialogInterface dialog) {
              myTask.cancel(true);
              //finish();
          }
    });
Run Code Online (Sandbox Code Playgroud)

这样,当我按下后退按钮时,上面的OnCancelListener取消了对话框和任务.如果要在后退时完成整个活动,也可以添加finish().请记住将异步任务声明为如下变量:

    MyAsyncTask myTask=null;
Run Code Online (Sandbox Code Playgroud)

并像这样执行你的异步任务:

    myTask = new MyAsyncTask();
    myTask.execute();
Run Code Online (Sandbox Code Playgroud)

  • 您在上面发布的解决方案和解决方案之间有什么区别可以添加动作监听器? (48认同)
  • 在显示对话框之前,您不必如此明确地设置取消侦听器,有一个`show`方法接受取消侦听器作为其参数之一. (2认同)

odi*_*ity 10

我花了一段时间搞清楚这一点,我想要的只是一个如何做到的简单例子,所以我想我会发布我是如何做到的.这是一些更新库的代码,并有一个进度对话框,显示已更新的书籍数量,并在用户解除对话框时取消:

private class UpdateLibrary extends AsyncTask<Void, Integer, Boolean>{
    private ProgressDialog dialog = new ProgressDialog(Library.this);
    private int total = Library.instance.appState.getAvailableText().length;
    private int count = 0;

    //Used as handler to cancel task if back button is pressed
    private AsyncTask<Void, Integer, Boolean> updateTask = null;

    @Override
    protected void onPreExecute(){
        updateTask = this;
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setOnDismissListener(new OnDismissListener() {               
            @Override
            public void onDismiss(DialogInterface dialog) {
                updateTask.cancel(true);
            }
        });
        dialog.setMessage("Updating Library...");
        dialog.setMax(total);
        dialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... arg0) {
            for (int i = 0; i < appState.getAvailableText().length;i++){
                if(isCancelled()){
                    break;
                }
                //Do your updating stuff here
            }
        }

    @Override
    protected void onProgressUpdate(Integer... progress){
        count += progress[0];
        dialog.setProgress(count);
    }

    @Override
    protected void onPostExecute(Boolean finished){
        dialog.dismiss();
        if (finished)
            DialogHelper.showMessage(Str.TEXT_UPDATELIBRARY, Str.TEXT_UPDATECOMPLETED, Library.instance);
        else 
            DialogHelper.showMessage(Str.TEXT_UPDATELIBRARY,Str.TEXT_NOUPDATE , Library.instance);
    }
}
Run Code Online (Sandbox Code Playgroud)


jkh*_*uw1 9

在你的活动中创建一些成员变量

YourAsyncTask mTask;
Dialog mDialog;
Run Code Online (Sandbox Code Playgroud)

将这些用于对话和任务;

在onPause()中只需调用

if(mTask!=null) mTask.cancel(); 
if(mDialog!=null) mDialog.dismiss();
Run Code Online (Sandbox Code Playgroud)


Rah*_*ina 5

我想改进代码.当你canel了aSyncTaskonCancelled()(回调方法aSyncTask)会导致自动调用,在那里你可以隐藏你的progressBarDialog.

您也可以包含此代码:

public class information extends AsyncTask<String, String, String>
    {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... arg0) {
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            this.cancel(true);
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onCancelled() {
            Toast.makeText(getApplicationContext(), "asynctack cancelled.....", Toast.LENGTH_SHORT).show();
            dialog.hide(); /*hide the progressbar dialog here...*/
            super.onCancelled();
        }

    }
Run Code Online (Sandbox Code Playgroud)