AsyncQueryHandler的使用方法

来源:互联网 发布:生化危机6存档数据损坏 编辑:程序博客网 时间:2024/05/13 15:25

/**     * 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)
由上面的参数可以看出跟一般的数据库语句是一样的,看看token参数,是为了区分每次查询的,就是在回调方法中会传入该参数,让用户知道这次回调是响应哪次查询的。

这token只要用户自己能区分就行,最好是唯一性的。还有cookie,由字面可以知道,在complete后在会传给回调方法。



这个类就是另开线程执行数据的操作,然后在调用startxxx()的线程回调onCompletexxx()方法。

AsyncQueryHandler extends Handler。

构造的时候,调用父类的空参构造方法Handler(),即是说当前线程必须调用Looper.prepare()或者是主线程。处理onCompletexxx()方法就是在该Hanlder的handleMessage()

中,而处理数据库操作的逻辑是在AsyncQueryHandler的内部类protected class WorkerHandler extends Handler中执行,看下面的AsyncQueryHandler构造方法源码可以知

道,传入WorkerHandler的looper是另开一个子线程的,所以WorkerHandler的handlerMessage()方法会在另开的子线程中调用。HandlerThread其实就是一个Thread。

public AsyncQueryHandler(ContentResolver cr) {        super();        mResolver = new WeakReference<ContentResolver>(cr);        synchronized (AsyncQueryHandler.class) {            if (sLooper == null) {                HandlerThread thread = new HandlerThread("AsyncQueryWorker");                thread.start();                sLooper = thread.getLooper();            }        }        mWorkerThreadHandler = createHandler(sLooper);    }

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();        }    }


AsyncQueryHandler#handleMessage()

 @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;        }    }}


Handler、Looper、MessageQueue


0 0
原创粉丝点击