如何取消Android中的AsyncTask?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何取消Android中的AsyncTask?相关的知识,希望对你有一定的参考价值。

嗨onCancel对话框我想取消服务器调用,但我面临的问题,即使我取消任务,它命中我的服务器并修改数据。我该如何解决这个问题?以下是我的代码..


     private class UserBoardingTask extends AsyncTask {
            @Override
            protected void onPreExecute() {
                progressDialog = new ProgressDialog(getActivity());
                progressDialog.setMessage(getResources().getString(R.string.please_wait));
                progressDialog.setIndeterminate(false);
                progressDialog.setCancelable(true);
                progressDialog.setOnCancelListener(new OnCancelListener() {
                @Override
                    public void onCancel(DialogInterface dialog) {
                         if (userOnBoardingTask!= null && userOnBoardingTask.getStatus() != AsyncTask.Status.FINISHED && !userOnBoardingTask.isCancelled()) {
                             userOnBoardingTask.cancel(true);

                           }      
                    }
                });
                progressDialog.show();
            }

            @Override
            protected Void doInBackground(String... urls) {
                String boardingURL=null;


                boardingURL= getUrl();


                UserOnBoardingDTO userOnBoardingDetailsDTO = AppStateManager.getUserBoardingDetails();
                try{

                    RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);

                }   


                   catch (Exception e) {
                   errorMessage=getResources().getString(R.string.unknown_exp);
                    }
                return null;
                }

            @Override
            protected void onCancelled() {
                super.onCancelled();
                closeProgressDialog();
                errorMessage="";
                AppStateManager.setUserBoardingDetails(null);
                userOnBoardingTask=null;

            }

            @Override
            protected void onPostExecute(Void res) {
                closeProgressDialog();
                userOnBoardingTask=null;
                if(!FieldsValidator.isBlank(errorMessage)){
                    CommonUtil.showToast(getActivity(),errorMessage);
                    errorMessage="";
                    return; 
                }

答案

偶尔检查一下isCancelled()

 protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled()) break;
    }
    return null;
 }

另一种解决方案是

protected void onProgressUpdate(String... progress1) {
                         if(condition){

                                break;
                        }
        }
另一答案

将对话框移出异步任务,仅在未取消对话框时启动任务。

另一答案

实际上问题不是你的asynsTask终止,但是如果在asynsTask终止之前已经完成服务器命中服务器,那么你也必须中断你的服务器请求。只需使用abort方法终止你的服务器请求。

另一答案

userOnBoardingTask在哪里声明,以及它被分配给运行任务的引用?我怀疑当任务试图取消它时,它不会存储正确的引用。

我不确定这是否是你问题的真正原因。但是,如果它打算用于当前的任务,你肯定可以摆脱这个变量。只需在取消侦听器上更改对话框:

private class UserBoardingTask extends AsyncTask<String, Void, Void> {

@Override
protected void onPreExecute() {

    // ...

    progressDialog.setOnCancelListener(new OnCancelListener() {

        @Override
        public void onCancel(DialogInterface dialog) {
            if (UserBoardingTask.this.getStatus() != AsyncTask.Status.FINISHED 
                && UserBoardingTask.this.isCancelled()) {
                UserBoardingTask.this.cancel(true);
            }
        }
    });

实际上你可以省略UserBoardingTask.this短语,因为内部类可以直接指向嵌套类的字段,只要名称不被内部类成员的名称遮盖:

private class UserBoardingTask extends AsyncTask<String, Void, Void> {

@Override
protected void onPreExecute() {

    // ...

    progressDialog.setOnCancelListener(new OnCancelListener() {

        @Override
        public void onCancel(DialogInterface dialog) {
            if (getStatus() != AsyncTask.Status.FINISHED && isCancelled()) {
                cancel(true);
            }
        }
    });

编辑

另一点是,在向服务器发送请求之前,您可以在doInBackground内部检查,您可以检查任务是否未被取消

        // ...

        @Override
        protected Void doInBackground(String... urls) {

            // ...

            try {
                if(isCancelled()) {
                   throw new Exception("Exit: task cancelled!");
                }

                RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);

            // ...
另一答案
RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);

上面的代码命中了服务器。因此,您必须在取消之间验证代码的执行。

尝试这样的事情

  try{
if(!userOnBoardingTask.isCancelled())
{
                RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);
}

            }   


               catch (Exception e) {
               errorMessage=getResources().getString(R.string.unknown_exp);
                }

还行吧。如果用户在ResetAPIManager代码执行之前取消该任务。假设用户尝试在服务器调用启动后取消任务,则必须告知已修改或重新修改服务器数据或无法取消或向用户发送某些消息。所有这些都是通过获取服务器响应来完成的,并在服务器响应发生变化时验证服

使用这样的东西

 Var rsponse = RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password);

验证onPostExecute()或OnCancelled()方法中的响应消息。

另一答案

如果在访问此方法后取消asynctask RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password);异步任务将在运行上面的代码后取消,所以你应该通过在RestAPIManager类中创建一个新方法来解决这个问题,并在你的asyncTask中调用OnCancelled方法中的方法。

以上是关于如何取消Android中的AsyncTask?的主要内容,如果未能解决你的问题,请参考以下文章

带有进度对话框取消的 Android AsyncTask

Android开发--取消AsyncTask

如何在Android开发中用AsyncTask异步更新UI界面

差异b / w在AsyncTask Android中取消(true)和取消(false)

即使使用取消方法也无法取消 AsyncTask 中的 doInBackground 进程

如何从 android 中的 AsyncTask 获取 UI 参考