Calling this method will result in
onCancelled(Object)
being invoked
on the UI thread afterdoInBackground(Object[])
returns. Calling this
method guarantees thatonPostExecute(Object)
is never invoked.
这是Android中的错误吗?
更多观察:
>从任一线程调用cancel(false)按照中的规定工作
文档.
>从UI任务调用cancel(true)不会调用onPostExecute(),也不会抛出下面的logcat跟踪中看到的InterruptedException.
>甚至在doInBackground()返回之前,从任何线程调用cancel(false / true)有时会调用onCancelled().这显然违反了文档which states:
Calling this method will result in onCancelled(Object) being invoked
on the UI thread afterdoInBackground(Object[])
returns.
代码:(在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()
解决方法
>您的代码在Android 2上运行,但您引用的是Android 4的文档.问题是在Android 2和Android 4之间,cancel()上的行为发生了变化.
Runs on the UI thread after doInBackground. The specified result is
the value returned by doInBackground or null if the task was cancelled
or an exception occured.
Runs on the UI thread after doInBackground. The specified result is the value returned by doInBackground. This method won’t be invoked if the task was cancelled.