执行AsyncTask onCancelled()和AsyncTask.doInBackground()的时间

时间:2011-07-10 13:20:07

标签: android

根据AsyncTask.cancel method的Android参考,明确定义了onCancelled()和doInBackground()之间的时间:

  

调用此方法将导致在doInBackground(Object [])返回后在UI线程上调用onCancelled(Object)。调用此方法可确保永远不会调用onPostExecute(Object)

但是,查看我的logcat,我可以看到onCancelled()方法在doInBackground()方法返回之前执行。

07-10 12:38:57.000: VERBOSE/AsyncTask(7473): doInBackground entered
07-10 12:38:57.000: VERBOSE/AsyncTask(7473): AsyncTask attempting to take the lock
07-10 12:38:57.000: VERBOSE/AsyncTask(7473): AsyncTask got the lock
07-10 12:38:57.420: VERBOSE/AsyncTask(7473): Start Item[0].state = 0
07-10 12:38:57.933: VERBOSE/AsyncTask(7473): onProgressUpdate entered
07-10 12:38:57.940: VERBOSE/AsyncTask(7473): onProgressUpdate exited
07-10 12:38:58.320: VERBOSE/(7473): onCancelListener cancelling AsyncTask
07-10 12:38:58.400: VERBOSE/AsyncTask(7473): onCancelled entered
07-10 12:38:58.400: VERBOSE/AsyncTask(7473): onCancelled exited
07-10 12:38:58.560: VERBOSE/AsyncTask(7473): Started checking file URL
07-10 12:38:58.601: VERBOSE/FileHost(7473): checkFile entered
07-10 12:38:58.641: VERBOSE/FileHost(7473): checkFile checking URI
07-10 12:38:58.691: DEBUG/dalvikvm(7473): threadid=19 wakeup: interrupted
07-10 12:38:58.710: VERBOSE/AsyncTask(7473): AsyncTask released the lock
07-10 12:38:58.710: VERBOSE/AsyncTask(7473): doInBackground exited

使用调试器并在onCancelled()方法和doInBackground()方法结束时设置断点,我还可以看到在doInBackground()结束之前调用onCancelled()。

我是否有某些方法在我的AsyncTask中错误编码了某些内容,以便在Android Reference和我的应用程序行为之间产生这种差异?

编辑为Gallal添加一些代码:

@Gallal,活动包含这段代码。

private class OnCancelListener implements AddUrlDialog.CancelListener {
  @Override
  public void cancel() {
    if (addUrlInProgress == true) {
      addUrlInProgress = false;
      Log.v(TAG, "onCancelListener cancelling AsyncTask");
      addUrlControl.stopUpdates(true);
      AddUrlDialog.dismiss();
    }
  } 
}

在addUrlControl.stopUpdates()方法中调用AsyncTask.cancel。

public void stopUpdates(boolean cleanupLists) {
  if (asyncTaskExited != true) {
      cancelRequest = true; 
        addUrlAsyncTask.cancel(true);
        //TEST httpRequest.abort(); // Also sends an abort to the HTTP request
  }
}

AsyncTask doInBackground方法看起来像这样。

@Override
protected Void doInBackground(Void... v) {
  Log.v(TAG, "doInBackground entered");

    netConn = addUrlControl.myApp.getNetConn();
    client = netConn.getHttpClient();

    try {
      doInBackgroundBody();
  } catch (Throwable t) {
      Log.e(TAG, "doInBackgroundBody threw an exception: ", t);
  } finally {
      addUrlControl.myApp.releaseNetConn();
  }

    Log.v(TAG, "doInBackground exited");        
    return null;
}

3 个答案:

答案 0 :(得分:4)

我可以确认(正如你们中的一些人已经说过的那样)bug in the Android source for 2.x versions使onCancelled()cancel()之后和doInBackground()完成之前被调用。

所以,如果你正在onCancelled()进行清理,那么你将在AsyncTask运行的同时实际执行此操作,这将使你的应用程序崩溃!这使我们改变了设计......

希望它有所帮助!

答案 1 :(得分:0)

什么是

addUrlAsyncTask.cancel(true);

返回?

如果任务无法中断,它将一直运行直到完成。

你在doInBackgroundBody()里面有一个循环吗?即doInBackground()的以下实现将捕获调用myTask.cancel(true)时抛出的InterruptedException,因此循环将继续,直到循环条件的计算结果为false。

        int count = 0;
        while(count++ < 10){
            try {
                Log.d("MyAsyncTask", "WORKING doInBackground() is cancelled: " + this.isCancelled());
                Thread.sleep(1000);

            } catch (Exception e) {
                e.printStackTrace();
                //break or return missing here to end the loop
            }
        }

答案 2 :(得分:0)

这似乎与我无法找到大量信息的错误有关。除了我有同样的问题。根据这个讨论:AsyncTask's cancel method - possible bug它是cancel()代码中的一个竞赛,应该在post froyo版本中修复。