从AsyncTask.cancel(true)
内拨打doInBackground()
,而不是拨打onCancelled()
,Android会拨打onPostExecute()
。但是as per the documentation:
调用此方法将导致调用
onCancelled(Object)
在doInBackground(Object[])
返回后的UI线程上。 打电话给这个 方法保证永远不会调用onPostExecute(Object)
。
这是Android中的错误吗?
更多观察结果:
cancel(false)
按照中指定的方式工作
文档。cancel(true)
不调用onPostExecute()
,也不会抛出下面的logcat跟踪中的InterruptedException
。cancel(false/true)
返回之前,从任何线程调用onCancelled()
有时也会调用doInBackground()
。这显然违反了文档which states:调用此方法将导致调用onCancelled(Object) 在
doInBackground(Object[])
返回后的UI线程上。
代码:(在Android 2.2设备上测试)
protected Void doInBackground(Void... params) {
Log.d(TAG, "started doInBackground()");
while (!isCancelled()) {
boolean ret = cancel(true);
Log.d(TAG, "cancel() returned: " + ret);
}
Log.d(TAG, "returning from doInBackground()");
return null;
}
Logcat输出
04-15 21:38:55.519: D/MyTask(27597): started doInBackground()
04-15 21:38:55.589: W/AsyncTask(27597): java.lang.InterruptedException
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1254)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:219)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask.get(FutureTask.java:82)
04-15 21:38:55.589: W/AsyncTask(27597): at android.os.AsyncTask$3.done(AsyncTask.java:196)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask$Sync.innerCancel(FutureTask.java:293)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask.cancel(FutureTask.java:75)
04-15 21:38:55.589: W/AsyncTask(27597): at android.os.AsyncTask.cancel(AsyncTask.java:325)
04-15 21:38:55.589: W/AsyncTask(27597): at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:31)
04-15 21:38:55.589: W/AsyncTask(27597): at com.example.test.TestActivity$MyTask.doInBackground(TestActivity.java:1)
04-15 21:38:55.589: W/AsyncTask(27597): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-15 21:38:55.589: W/AsyncTask(27597): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-15 21:38:55.589: W/AsyncTask(27597): at java.lang.Thread.run(Thread.java:1096)
04-15 21:38:55.589: D/MyTask(27597): cancel() returned: true
04-15 21:38:55.589: D/MyTask(27597): returning from doInBackground()
04-15 21:38:55.659: D/MyTask(27597): onPostExecute()
答案 0 :(得分:3)
有一个例外,因为你调用cancel(true)会向运行doInBackground()的线程发送一个中断 - 但是,在这种情况下,你从doInBackground()中调用cancel(true),从而导致线程立即向自己发送中断。
您的代码在Android 2上运行,但您引用的是Android 4的文档。问题是在Android 2和Android 4之间,cancel()上的行为发生了变化。
在doInBackground之后在UI线程上运行。指定的结果是 doInBackground返回的值,如果任务被取消,则返回null 或发生例外。
在doInBackground之后在UI线程上运行。指定的结果是 doInBackground返回的值。如果,则不会调用此方法 任务被取消了。
答案 1 :(得分:1)
您应该返回null并在onPostExecute中处理返回。