diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch) | |
tree | 35051494d2af230dce54d6b31c6af8fc24091316 /core/java/android/content/AsyncQueryHandler.java | |
download | frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2 |
Initial Contribution
Diffstat (limited to 'core/java/android/content/AsyncQueryHandler.java')
-rw-r--r-- | core/java/android/content/AsyncQueryHandler.java | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/core/java/android/content/AsyncQueryHandler.java b/core/java/android/content/AsyncQueryHandler.java new file mode 100644 index 0000000..48f1bc7 --- /dev/null +++ b/core/java/android/content/AsyncQueryHandler.java @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +import android.database.Cursor; +import android.net.Uri; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.util.Log; + +/** + * A helper class to help make handling asynchronous {@link ContentResolver} + * queries easier. + */ +public abstract class AsyncQueryHandler extends Handler { + private static final String TAG = "AsyncQuery"; + private static final boolean localLOGV = false; + + private static final int EVENT_ARG_QUERY = 1; + private static final int EVENT_ARG_INSERT = 2; + private static final int EVENT_ARG_UPDATE = 3; + private static final int EVENT_ARG_DELETE = 4; + + /* package */ ContentResolver mResolver; + + private static Looper sLooper = null; + + private Handler mWorkerThreadHandler; + + protected static final class WorkerArgs { + public Uri uri; + public Handler handler; + public String[] projection; + public String selection; + public String[] selectionArgs; + public String orderBy; + public Object result; + public Object cookie; + public ContentValues values; + } + + protected class WorkerHandler extends Handler { + public WorkerHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + WorkerArgs args = (WorkerArgs) msg.obj; + + int token = msg.what; + int event = msg.arg1; + + switch (event) { + case EVENT_ARG_QUERY: + Cursor cursor; + try { + cursor = mResolver.query(args.uri, args.projection, + args.selection, args.selectionArgs, + args.orderBy); + } catch (Exception e) { + cursor = null; + } + + args.result = cursor; + break; + + case EVENT_ARG_INSERT: + args.result = mResolver.insert(args.uri, args.values); + break; + + case EVENT_ARG_UPDATE: + int r = mResolver.update(args.uri, args.values, args.selection, + args.selectionArgs); + args.result = new Integer(r); + break; + + case EVENT_ARG_DELETE: + int r2 = mResolver.delete(args.uri, args.selection, args.selectionArgs); + args.result = new Integer(r2); + break; + + } + + // passing the original token value back to the caller + // on top of the event values in arg1. + Message reply = args.handler.obtainMessage(token); + reply.obj = args; + reply.arg1 = msg.arg1; + + if (localLOGV) { + Log.d(TAG, "WorkerHandler.handleMsg: msg.arg1=" + msg.arg1 + + ", reply.what=" + reply.what); + } + + reply.sendToTarget(); + } + } + + public AsyncQueryHandler(ContentResolver cr) { + super(); + mResolver = cr; + synchronized (AsyncQueryHandler.class) { + if (sLooper == null) { + HandlerThread thread = new HandlerThread("AsyncQueryWorker"); + thread.start(); + + sLooper = thread.getLooper(); + } + } + mWorkerThreadHandler = createHandler(sLooper); + } + + protected Handler createHandler(Looper looper) { + return new WorkerHandler(looper); + } + + /** + * This method begins an asynchronous query. When the query is done + * {@link #onQueryComplete} is called. + * + * @param token A token passed into {@link #onQueryComplete} to identify + * the query. + * @param cookie An object that gets passed into {@link #onQueryComplete} + */ + public void startQuery(int token, Object cookie, Uri uri, + String[] projection, String selection, String[] selectionArgs, + String orderBy) { + // Use the token as what so cancelOperations works properly + Message msg = mWorkerThreadHandler.obtainMessage(token); + msg.arg1 = EVENT_ARG_QUERY; + + WorkerArgs args = new WorkerArgs(); + args.handler = this; + args.uri = uri; + args.projection = projection; + args.selection = selection; + args.selectionArgs = selectionArgs; + args.orderBy = orderBy; + args.cookie = cookie; + msg.obj = args; + + mWorkerThreadHandler.sendMessage(msg); + } + + /** + * Attempts to cancel operation that has not already started. Note that + * there is no guarantee that the operation will be canceled. They still may + * result in a call to on[Query/Insert/Update/Delete]Complete after this + * call has completed. + * + * @param token The token representing the operation to be canceled. + * If multiple operations have the same token they will all be canceled. + */ + public final void cancelOperation(int token) { + mWorkerThreadHandler.removeMessages(token); + } + + /** + * This method begins an asynchronous insert. When the insert operation is + * done {@link #onInsertComplete} is called. + * + * @param token A token passed into {@link #onInsertComplete} to identify + * the insert operation. + * @param cookie An object that gets passed into {@link #onInsertComplete} + * @param uri the Uri passed to the insert operation. + * @param initialValues the ContentValues parameter passed to the insert operation. + */ + public final void startInsert(int token, Object cookie, Uri uri, + ContentValues initialValues) { + // Use the token as what so cancelOperations works properly + Message msg = mWorkerThreadHandler.obtainMessage(token); + msg.arg1 = EVENT_ARG_INSERT; + + WorkerArgs args = new WorkerArgs(); + args.handler = this; + args.uri = uri; + args.cookie = cookie; + args.values = initialValues; + msg.obj = args; + + mWorkerThreadHandler.sendMessage(msg); + } + + /** + * This method begins an asynchronous update. When the update operation is + * done {@link #onUpdateComplete} is called. + * + * @param token A token passed into {@link #onUpdateComplete} to identify + * the update operation. + * @param cookie An object that gets passed into {@link #onUpdateComplete} + * @param uri the Uri passed to the update operation. + * @param values the ContentValues parameter passed to the update operation. + */ + public final void startUpdate(int token, Object cookie, Uri uri, + ContentValues values, String selection, String[] selectionArgs) { + // Use the token as what so cancelOperations works properly + Message msg = mWorkerThreadHandler.obtainMessage(token); + msg.arg1 = EVENT_ARG_UPDATE; + + WorkerArgs args = new WorkerArgs(); + args.handler = this; + args.uri = uri; + args.cookie = cookie; + args.values = values; + args.selection = selection; + args.selectionArgs = selectionArgs; + msg.obj = args; + + mWorkerThreadHandler.sendMessage(msg); + } + + /** + * This method begins an asynchronous delete. When the delete operation is + * done {@link #onDeleteComplete} is called. + * + * @param token A token passed into {@link #onDeleteComplete} to identify + * the delete operation. + * @param cookie An object that gets passed into {@link #onDeleteComplete} + * @param uri the Uri passed to the delete operation. + * @param selection the where clause. + */ + public final void startDelete(int token, Object cookie, Uri uri, + String selection, String[] selectionArgs) { + // Use the token as what so cancelOperations works properly + Message msg = mWorkerThreadHandler.obtainMessage(token); + msg.arg1 = EVENT_ARG_DELETE; + + WorkerArgs args = new WorkerArgs(); + args.handler = this; + args.uri = uri; + args.cookie = cookie; + args.selection = selection; + args.selectionArgs = selectionArgs; + msg.obj = args; + + mWorkerThreadHandler.sendMessage(msg); + } + + /** + * Called when an asynchronous query is completed. + * + * @param token the token to identify the query, passed in from + * {@link #startQuery}. + * @param cookie the cookie object that's passed in from {@link #startQuery}. + * @param cursor The cursor holding the results from the query. + */ + protected void onQueryComplete(int token, Object cookie, Cursor cursor) { + // Empty + } + + /** + * Called when an asynchronous insert is completed. + * + * @param token the token to identify the query, passed in from + * {@link #startInsert}. + * @param cookie the cookie object that's passed in from + * {@link #startInsert}. + * @param uri the uri returned from the insert operation. + */ + protected void onInsertComplete(int token, Object cookie, Uri uri) { + // Empty + } + + /** + * Called when an asynchronous update is completed. + * + * @param token the token to identify the query, passed in from + * {@link #startUpdate}. + * @param cookie the cookie object that's passed in from + * {@link #startUpdate}. + * @param result the result returned from the update operation + */ + protected void onUpdateComplete(int token, Object cookie, int result) { + // Empty + } + + /** + * Called when an asynchronous delete is completed. + * + * @param token the token to identify the query, passed in from + * {@link #startDelete}. + * @param cookie the cookie object that's passed in from + * {@link #startDelete}. + * @param result the result returned from the delete operation + */ + protected void onDeleteComplete(int token, Object cookie, int result) { + // Empty + } + + @Override + public void handleMessage(Message msg) { + WorkerArgs args = (WorkerArgs) msg.obj; + + if (localLOGV) { + Log.d(TAG, "AsyncQueryHandler.handleMessage: msg.what=" + msg.what + + ", msg.arg1=" + msg.arg1); + } + + int token = msg.what; + int event = msg.arg1; + + // pass token back to caller on each callback. + switch (event) { + case EVENT_ARG_QUERY: + onQueryComplete(token, args.cookie, (Cursor) args.result); + break; + + case EVENT_ARG_INSERT: + onInsertComplete(token, args.cookie, (Uri) args.result); + break; + + case EVENT_ARG_UPDATE: + onUpdateComplete(token, args.cookie, (Integer) args.result); + break; + + case EVENT_ARG_DELETE: + onDeleteComplete(token, args.cookie, (Integer) args.result); + break; + } + } +} |