android.os.OperationCanceledException - What it means

01-29 01:33:12.969   434   470 I ActivityManager: Displayed com.google.android.talk/.SigningInActivity: +997ms
01-29 01:33:13.039  6159  6160 D dalvikvm: GC_CONCURRENT freed 506K, 10% free 6609K/7303K, paused 59ms+7ms, total 106ms
01-29 01:33:13.039  6159  6170 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 18ms
01-29 01:33:13.039  6159  6159 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 18ms
01-29 01:33:13.149  6159  6174 W dalvikvm: threadid=13: thread exiting with uncaught exception (group=0x40be6498)
01-29 01:33:13.239  6159  6160 D dalvikvm: GC_CONCURRENT freed 513K, 10% free 6608K/7303K, paused 21ms+74ms, total 142ms
01-29 01:33:13.239  6159  6170 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 97ms
01-29 01:33:13.239  6159  6159 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 7ms
01-29 01:33:13.319  6159  6174 E test    : Exception
01-29 01:33:13.419  6159  6160 D dalvikvm: GC_CONCURRENT freed 508K, 10% free 6612K/7303K, paused 17ms+11ms, total 77ms
01-29 01:33:13.419  6159  6170 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 33ms
01-29 01:33:13.429  6159 13235 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 40ms
01-29 01:33:13.469  6159  6174 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 79ms
01-29 01:33:13.469  6159 13236 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 62ms

01-29 01:33:13.659  6159  6160 D dalvikvm: GC_CONCURRENT freed 573K, 12% free 6482K/7303K, paused 20ms+17ms, total 137ms
01-29 01:33:13.669  6159  6174 E AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
01-29 01:33:13.669  6159  6174 E AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground()
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.lang.Thread.run(Thread.java:856)
01-29 01:33:13.669  6159  6174 E AndroidRuntime: Caused by: android.os.OperationCanceledException: The operation has been canceled.
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.content.CursorLoader.loadInBackground(CursorLoader.java:60)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.content.CursorLoader.loadInBackground(CursorLoader.java:43)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:301)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:68)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:56)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-29 01:33:13.669  6159  6174 E AndroidRuntime:  ... 4 more

01-29 01:33:13.779   434 12795 W ActivityManager: Force-killing crashed app com.google.android.talk at watcher's request
01-29 01:33:13.839   434 12795 I ActivityManager: Process com.google.android.talk (pid 6159) has died.


The exception occurs in process com.google.android.talk in CursorLoader's method.
The android.os.OperationCanceledException type is thrown when an operation in progress is canceled.

CursorLoader implements the Loader protocol for querying cursors, it queries the ContentResolver and returns a Cursor.
CursorLoader is built on AsyncTaskLoader to perform the cursor query on a background thread.

AsyncTask is loaded and its body doInBackground is executed.
AsyncTaskLoader::doInBackground => AsyncTaskLoader::onLoadInBackground => CursorLoader::loadInBackground().

In AsyncTaskLoader.java,
63        /* Runs on a worker thread */
64        @Override
65        protected D doInBackground(Void... params) {
66            if (DEBUG) Slog.v(TAG, this + " >>> doInBackground");
67            try {
68                D data = AsyncTaskLoader.this.onLoadInBackground();
69                if (DEBUG) Slog.v(TAG, this + "  <<< doInBackground");
70                return data;
71            } catch (OperationCanceledException ex) {
72                if (!isCancelled()) {
73                    // onLoadInBackground threw a canceled exception spuriously.
74                    // This is problematic because it means that the LoaderManager did not
75                    // cancel the Loader itself and still expects to receive a result.
76                    // Additionally, the Loader's own state will not have been updated to
77                    // reflect the fact that the task was being canceled.
78                    // So we treat this case as an unhandled exception.
79                    throw ex;
80                }
81                if (DEBUG) Slog.v(TAG, this + "  <<< doInBackground (was canceled)");
82                return null;
83            }
84        }

239    protected D onLoadInBackground() {
240        return loadInBackground();
241    }

In loadInBackground() @ CursorLoader.java
55    /* Runs on a worker thread */
56    @Override
57    public Cursor loadInBackground() {
58        synchronized (this) {
59            if (isLoadInBackgroundCanceled()) {
60                throw new OperationCanceledException(); <= Exception throws.
61            }
62            mCancellationSignal = new CancellationSignal();
63        }
64        try {
65            Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
66                    mSelectionArgs, mSortOrder, mCancellationSignal);
67            if (cursor != null) {
68                // Ensure the cursor window is filled
69                cursor.getCount();
70                registerContentObserver(cursor, mObserver);
71            }
72            return cursor;
73        } finally {
74            synchronized (this) {
75                mCancellationSignal = null;
76            }
77        }
78    }

If LoadInBackground is canceled, OperationCanceledException is thrown. The relavent code,
In isLoadInBackgroundCanceled() @ AsyncTaskLoader.java
325    public boolean isLoadInBackgroundCanceled() {
326        return mCancellingTask != null;
327    }

mCancellingTask is assigned when current LoadTask is cancelled and new LoadTask is set in another thread.
160    @Override
161    protected boolean onCancelLoad() {
162        if (DEBUG) Slog.v(TAG, "onCancelLoad: mTask=" + mTask);
163        if (mTask != null) {
164            if (mCancellingTask != null) {

183            } else {
184                boolean cancelled = mTask.cancel(false);
185                if (DEBUG) Slog.v(TAG, "cancelLoad: cancelled=" + cancelled);
186                if (cancelled) {
187                    mCancellingTask = mTask;
188                    cancelLoadInBackground();
189                }
190                mTask = null;
191                return cancelled;
192            }
193        }
194        return false;
195    }


In the class AccountManager used by google talk, it can seen that OperationCanceledException will be thrown if the some operation was canceled for any reason, including the user canceling the creation process, a credential request, the password prompt, etc.

The root cause is the on-going operation in AsyncTask is cancelled.

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值