如何取消Android中的AsynTask?

如何取消Android中的AsynTask?,android,android-asynctask,Android,Android Asynctask,Hi onCancel of dialog我想取消对服务器的调用,但我面临的问题是,即使我取消了任务,它也会击中我的服务器并修改数据。我如何解决这个问题?下面是我的代码 private class UserBoardingTask extends AsyncTask { @Override protected void onPreExecute() { progressDialog = new ProgressDia

Hi onCancel of dialog我想取消对服务器的调用,但我面临的问题是,即使我取消了任务,它也会击中我的服务器并修改数据。我如何解决这个问题?下面是我的代码

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; } 私有类UserBoardingTask扩展异步任务{ @凌驾 受保护的void onPreExecute(){ progressDialog=新建progressDialog(getActivity()); progressDialog.setMessage(getResources().getString(R.string.please_wait)); progressDialog.setUndeterminate(false); progressDialog.setCancelable(真); progressDialog.setOnCancelListener(新的OnCancelListener(){ @凌驾 public void onCancel(对话框接口对话框){ if(userOnBoardingTask!=null&&userOnBoardingTask.getStatus()!=AsyncTask.Status.FINISHED&&userOnBoardingTask.isCancelled()){ userOnBoardingTask.cancel(true); } } }); progressDialog.show(); } @凌驾 受保护的Void doInBackground(字符串…URL){ 字符串boardingURL=null; boardingURL=getUrl(); UserOnBoardingDTO UserOnBoardingDetailsTo=AppStateManager.getUserBoardingDetails(); 试一试{ RestAPIManager.putToNSWebService(boardingURL、UserOnBoardingDetailsTo、用户名、密码); } 捕获(例外e){ errorMessage=getResources().getString(R.string.unknown\u exp); } 返回null; } @凌驾 受保护的void onCancelled(){ super.onCancelled(); closeProgressDialog(); errorMessage=“”; AppStateManager.setUserBoardingDetails(null); userOnBoardingTask=null; } @凌驾 受保护的void onPostExecute(void res){ closeProgressDialog(); userOnBoardingTask=null; 如果(!FieldsValidator.isBlank(errorMessage)){ showtoost(getActivity(),errorMessage); errorMessage=“”; 返回; }
偶尔检查一下
isCancelled()

 protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled()) break;
    }
    return null;
 }
另一个解决办法是

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

                                break;
                        }
        }

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

哪里声明了
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);
            }
        }
    });
编辑

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

        // ...

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

            // ...

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

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

            // ...

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

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);
                }
 Var rsponse = RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password);
这是正常的。如果用户在ResetAPIManager代码执行之前取消任务。假设用户尝试在服务器调用启动后取消任务,则必须向用户告知已修改或重新修改的服务器数据或无法取消或某些消息。所有操作都通过获取服务器响应完成,并验证服务器响应是否已更改

用这样的东西

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

            }   


               catch (Exception e) {
               errorMessage=getResources().getString(R.string.unknown_exp);
                }
 Var rsponse = RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password);

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

如果在访问此方法后取消异步任务
RestAPIManager.PuttonWebService(boardingURL、UserOnBoardingDetailsTo、用户名、密码)
异步任务将在运行上述代码后取消,因此您应该在
RestAPIManager
类中创建一个新方法,并在
OnCancelled
方法中从异步任务中调用该方法来纠正此问题。

简短回答:不可能通过简单的取消来停止数据发布。一旦异步任务运行,即使您将发生中途数据发布取消。取消操作只需简单运行即可完成 查看此帖子
[

但是OP在DoinBackground中没有循环然后我提供了另一个解决方案Dude然后使用了第二个解决方案Dear我在我的片段中将AsyncTask引用声明为私有静态UserOnBoardingTask UserOnBoardingTask;变量,然后单击按钮实例化它。如果它是staic,那么它不是实例变量:)。它在哪里分配了引用要运行任务,请显示代码,并在其周围显示一些“上下文代码:)私有静态NorthStarUserOnBoardingTask userOnBoardingTask;//在frGaging中,单击按钮调用userOnBoardingTask=new NorthStarUserOnBoardingTask();userOnBoardingTask.execute();好的,看来我的建议并不能解决您的问题,但无论如何,您可以利用它使您的代码“更干净”。除非存在一些通信问题,否则请求将在
AsyncTask之前很久发送和交付。取消将被调用-至少这不是很可预测的行为。无论如何,调用abort()这是个好主意,具体取决于
RestAPIManager
实现中的内容。