[Android Notes] AsyncQueryHandler source code analysis, asyncqueryhandler

Source: Internet
Author: User

[Android Notes] AsyncQueryHandler source code analysis, asyncqueryhandler
The AsyncQueryHandler class is used to provide asynchronous database operations (add, delete, modify, and query. This article analyzes this class from the source code perspective.
1. AsyncQueryHandlerUsage:

AsyncQueryHandler handler = new AsyncQueryHandler(this.getContentResolver()){@Overrideprotected void onQueryComplete(int token, Object cookie,Cursor cursor){}@Overrideprotected void onUpdateComplete(int token, Object cookie, int result){}@Overrideprotected void onInsertComplete(int token, Object cookie, Uri uri){}@Overrideprotected void onDeleteComplete(int token, Object cookie, int result){}};handler.startQuery(token, cookie, uri, projection, selection, selectionArgs, orderBy);handler.startDelete(token, cookie, uri, selection, selectionArgs);handler.startInsert(token, cookie, uri, initialValues);handler.startUpdate(token, cookie, uri, values, selection, selectionArgs);

2. Source Code Analysis

Before analyzing the source code, grasp this class as a whole: Each AsyncQueryHandler object opens a background thread, and executes data interaction with the ContentProvider component in the thread for addition, deletion, modification, and query. During the call, the requests can be packaged and sent to the background thread through the AsyncQueryHandler. startXXX method. After the related processing is completed, the results will be asynchronously returned to the main thread and the AsyncQueryHandler. onXXXComplete method will be called to notify the caller. The caller needs to pass in an integer token as the identifier of the request each time. When the request is called back, the token is returned to help the caller determine which request this is.


AsyncQueryHandler is an abstract class and cannot be directly instantiated. Note the following:

public abstract class AsyncQueryHandler extends Handler

It encapsulates logoff and Handler internally, and the message loop works in the subthread. Four constants are provided to identify the current operation type. ContentResolver is injected by the constructor.
 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;

The handler of the worker thread, that is, the handleMessage method of mWorkThreadHandler, is responsible for operating the database:
Protected class WorkerHandler extends Handler {public WorkerHandler (low.lofter) {super (logoff) ;}@ 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); 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;} // return the result to the handleMessage of AsyncQueryHandler to process 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 ();}}

When constructing AsyncQueryHandler, it creates a HandlerThread and starts it, obtains its Loopers, constructs a subthread message loop using its Loopers, and binds it to mWorkThreadHandler:
Public AsyncQueryHandler (ContentResolver cr) {super (); mResolver = new WeakReference <ContentResolver> (cr); synchronized (AsyncQueryHandler. class) {if (slot = null) {HandlerThread thread = new HandlerThread ("AsyncQueryWorker"); thread. start (); // promoter thread, promoter thread message loop slots = thread. getLooper () ;}} mWorkerThreadHandler = createHandler (slotify);} protected Handler createHandler (Looper loler) {return new WorkerHandler (loler );}
This class provides WorkerArgs to encapsulate Request Parameters for database operations:
 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;    }

When the startXXX method is called, The WorkerArgs object is constructed and sent to mWorkThreadHandler as a message. After processing, the result is sent to AsyncQueryHandler: startXXX:
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; // note that this line sets Handler as itself, that is, AsyncQueryHandler args. uri = uri; args. projection = projection; args. selection = selection; args. selectionArgs = selectionArgs; args. orderBy = orderBy; args. cookie = cookie; msg. obj = args; mWorkerThreadHandler. sendMessage (msg); // submit it to the subthread for processing}

WorkerHandler:
Message reply = args. handler. obtainMessage (token); reply. obj = args; reply. arg1 = msg. arg1 ;... reply. sendToTarget (); // In the startXXX method, the target is set to AsyncQuertHandler.
Finally, the operation result is handled by the handleMessage of the AsyncQueryHandler class:
  @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;        }    }
The handleMessage method of the AsyncQueryHandler class calls back the onXXXcomplete series methods. We can override the onXXXcomplete method to obtain the database operation result.

This design is awesome !!!!









Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.