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

Android AsyncTask onCancelled()和AsyncTask.doInBackground()的执行时间,android,Android,根据的Android参考,onCancelled()和doInBackground()之间的时间是明确定义的: 调用此方法将导致在doInBackground(Object[])返回后在UI线程上调用onCancelled(Object)。调用此方法可确保永远不会调用onPostExecute(对象) 但是,查看我的logcat,我可以看到onCancelled()方法是在doInBackground()方法返回之前执行的 07-10 12:38:57.000: VERBOSE/AsyncTas

根据的Android参考,onCancelled()和doInBackground()之间的时间是明确定义的:

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

但是,查看我的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引用和我的应用程序行为之间的行为差异

编辑以添加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();
    }
  } 
}
AsyncTask.cancel在addUrlControl.stopUpdates()方法中调用

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;
}
什么是

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
            }
        }
int count=0;
而(计数+++<10){
试一试{
Log.d(“MyAsyncTask”,“工作doInBackground()被取消:“+this.isCancelled());
睡眠(1000);
}捕获(例外e){
e、 printStackTrace();
//在此处中断或返回缺失以结束循环
}
}

这似乎与一个bug有关,我还没有找到很多关于这个bug的信息。除了我也有同样的问题。根据这一讨论:取消()代码中的一场竞赛应该在froyo后期的构建中修复。

我可以确认(正如你们中的一些人已经说过的)有一种机制使得
onCancelled()
cancel()
之后和
doInBackground()
完成之前被调用

因此,如果您在
onCancelled()
中进行清理,您实际上会在AsyncTask运行的同时进行清理,这将使您的应用程序崩溃!这让我们改变了设计


希望有帮助

日志消息的顺序是否始终相同?您正在从不同的线程进行日志记录,因此logcat中的消息顺序可能会在应用程序运行之间发生变化,并且出现错误。@Herrrmann,日志消息的顺序是相同的。在调试器中放置断点表明在doInBackground()返回结束之前调用onCancelled()。@Hermann,cancel()方法返回true:07-10 16:24:03.743:VERBOSE/stopUpdates(4568):addUrlAsyncTask。cancel(true)返回true是的,我在doInBackground()方法中有一个循环。我还调用isCancelled()检查取消。isCancelled()方法返回true。谢谢提醒。我将玩一个后froyo构建,看看会发生什么。该死的,对我来说,它似乎仍然发生在2.3上。你是在使用中断异常来取消你的doInbackground功能吗?如果没有:我最后做的是在AsyncTask类中设置一个变量,并在doInbackground处理循环中检查该变量。然后在postExecute中,我可以通过检查该变量来区分已取消的任务和已完成的任务。除了调用AsyncTask.abort()之外,我还可以取消任何正在进行的HTTP请求(这将导致异常)。我还检查了AsyncTask中的isCancelled(),如果取消了,isCancelled()将返回true,因此我实际上知道AsyncTask是否已取消。只是onCancelled()方法调用的时间并不是我所期望的。不用担心,我不会为onCancelled()而烦恼。我似乎在这上面花费了太多的时间,我想我会改变我的设计。谢谢大家!
        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
            }
        }