android – AysncTask取消自身仍调用onPostExecute()

前端之家收集整理的这篇文章主要介绍了android – AysncTask取消自身仍调用onPostExecute()前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
从doInBackground()中调用AsyncTask.cancel(true)后,Android调用onPostExecute(),而不是调用onCancelled().但是 as per the documentation

Calling this method will result in onCancelled(Object) being invoked
on the UI thread after doInBackground(Object[]) returns. Calling this
method guarantees that onPostExecute(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 after doInBackground(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()

解决方法

>有一个例外,因为你调用cancel(true),它向运行doInBackground()的线程发送一个中断 – 但是,在这种情况下,你从doInBackground()中调用cancel(true),从而导致线程立即发送对自己的中断.
>您的代码在Android 2上运行,但您引用的是Android 4的文档.问题是在Android 2和Android 4之间,cancel()上的行为发生了变化.

Android 2.3.7 onPostExecute

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.

Android 4.0.1 onPostExecute

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.

原文链接:https://www.f2er.com/android/315645.html

猜你在找的Android相关文章