// Handler允许你去发送/处理消息message和Runnable对象。每个handler对象对应一个 // Thread和与这个Thread对应的MessageQueue。当你创建一个Handler的时候,它就和 // Thread以及相对应的MessageQueue绑定在一起。从绑定成功的那一刻开始,Handler // 就可以向MessageQueue中发送消息和Runnable对象,执行后就从消息队列退出。 // Handler是建立在Looper上,实现Thread的消息系统处理模型,实现消息异步处理。 // Thread默认是没有Looper和消息循环的,所以需要自己去添加。 // 消息循环和消息队列都是属于Thread,而Handler本身并不具有Looper和MessageQueue; // 但是消息系统的建立和交互,是Thread将Looper和MessageQueue交给某个Handler维护建立消息系统模型。 // 所以消息系统模型的核心就是Looper。消息循环和消息队列都是由Looper建立的,而建立Handler的关键就是这个Looper。 // 一个Thread同时可以对应多个Handler,一个Handler同时只能属于一个Thread。Handler属于哪个Thread取决于Handler在那个Thread中建立。 // (比如PHONE的消息通过某个Thread发出来,Callnotifer, callstateMonitor等handler都可以接受到,应该就是这个样子吧) // 在一个Thread中Looper也是唯一的,一个Thread对应一个Looper,建立Handler的Looper来自哪个Thread,Handler属于哪个Thread。 // 故建立Thread消息系统,就是将Thread的Looper交给Handler去打理,实现消息系统模型,完成消息的异步处理。 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; import java.lang.ref.WeakReference; /** * 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 */ final WeakReference<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) { final ContentResolver resolver = mResolver.get(); if (resolver == null) return; WorkerArgs args = (WorkerArgs) msg.obj; int token = msg.what; int event = msg.arg1; switch (event) { case EVENT_ARG_QUERY: Cursor cursor; try { cursor = resolver.query(args.uri, args.projection, args.selection, args.selectionArgs, args.orderBy); // Calling getCount() causes the cursor window to be filled, // which will make the first access on the main thread a lot faster. if (cursor != null) { cursor.getCount(); } } catch (Exception e) { Log.w(TAG, "Exception thrown during handling EVENT_ARG_QUERY", e); cursor = null; } args.result = cursor; break; case EVENT_ARG_INSERT: args.result = resolver.insert(args.uri, args.values); break; case EVENT_ARG_UPDATE: args.result = resolver.update(args.uri, args.values, args.selection, args.selectionArgs); break; case EVENT_ARG_DELETE: args.result = resolver.delete(args.uri, args.selection, args.selectionArgs); 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 = new WeakReference<ContentResolver>(cr); synchronized (AsyncQueryHandler.class) { if (sLooper == null) { HandlerThread thread = new HandlerThread("AsyncQueryWorker");//HandlerThread启动一个自带looper的线程 thread.start();//start()方法必须被调用,否则getLooper为null 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} * @param uri The URI, using the content:// scheme, for the content to * retrieve. * @param projection A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading data * from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null will * return all rows for the given URI. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in the order that they * appear in the selection. The values will be bound as Strings. * @param orderBy How to order the rows, formatted as an SQL ORDER BY * clause (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. */ 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;//调用者线程的handler对象 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 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; } } }
参考如下,这个写的真的是非常清楚
http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html