如何取消Android中的AsyncTask?

时间:2014-01-22 09:07:21

标签: android 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; 
                }

7 个答案:

答案 0 :(得分:2)

偶尔检查isCancelled()

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

另一个解决方案是

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

                                break;
                        }
        }

答案 1 :(得分:0)

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

答案 2 :(得分:0)

声明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);

            // ...

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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()方法中验证响应消息。

答案 5 :(得分:0)

如果在访问此方法后取消asynctask RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password);将在运行上述代码后取消异步任务,因此您应通过在RestAPIManager类内创建一个新方法并从asyncTask的OnCancelled方法内调用该方法来更正此问题。

答案 6 :(得分:0)

短分析器:通过简单的取消,它不可能停止数据过帐。一旦异步任务运行,即使您取消它,也会在中途发生数据发布。取消可以在简单运行中完成 检查这篇文章 [Android - Cancel AsyncTask Forcefully