Android O: AsyncQueryHandler分析
Posted ZhangJianIsAStark
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android O: AsyncQueryHandler分析相关的知识,希望对你有一定的参考价值。
本篇博客以android O的代码为例,分析一下AsyncQueryHandler这个类。
AsyncQueryHandler是用于在ContentProvider上执行异步操作的工具类。
我们直接来看看源码:
/**
* A helper class to help make handling asynchronous @link ContentResolver
* queries easier.
*/
//AsyncQueryHandler是一个抽象类
//使用时需要创建一个继承它的类,实现对应的回调接口,后文详述
public abstract class AsyncQueryHandler extends Handler
............
//弱引用
final WeakReference<ContentResolver> mResolver;
//静态的Looper
private static Looper sLooper = null;
private Handler mWorkerThreadHandler;
.............
//构造函数
public AsyncQueryHandler(ContentResolver cr)
super();
//弱引用传入的ContentResolver
mResolver = new WeakReference<ContentResolver>(cr);
//单例持有一个HandlerThread的looper
synchronized (AsyncQueryHandler.class)
if (sLooper == null)
HandlerThread thread = new HandlerThread("AsyncQueryWorker");
thread.start();
sLooper = thread.getLooper();
//创建WorkHandler
mWorkerThreadHandler = createHandler(sLooper);
protected Handler createHandler(Looper looper)
return new WorkerHandler(looper);
从上面的代码可以看出,AsyncQueryHandler的多个子类
将共用同一个HandlerThread处理任务。
AsyncQueryHandler提供了数据库基本的增删改查接口,
实现方式基本类似,我们以Query为例,看看具体的代码:
//token用于标记一个具体的请求
//其它参数就是查询数据库的操作
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是保存数据的内部类
WorkerArgs args = new WorkerArgs();
//保存AysncQueryHandler的子类
args.handler = this;
args.uri = uri;
args.projection = projection;
args.selection = selection;
args.selectionArgs = selectionArgs;
args.orderBy = orderBy;
args.cookie = cookie;
msg.obj = args;
//WorkHandler进行实际的处理
mWorkerThreadHandler.sendMessage(msg);
我们来看看WorkHandler的实现:
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;
//实际的cursor写入返回的参数
args.result = cursor;
break;
//处理其它case
...........
// passing the original token value back to the caller
// on top of the event values in arg1.
// 这个复用message还是做的蛮到位的.....
Message reply = args.handler.obtainMessage(token);
reply.obj = args;
reply.arg1 = msg.arg1;
......
//返回消息给AsyncQueryHandler的子类
reply.sendToTarget();
从上面的代码容易看出,当WorkHandler处理完毕消息后,
就会将数据返回给AsyncQueryHandler的子类,
于是handleMessage接口将被调用:
@Override
public void handleMessage(Message msg)
WorkerArgs args = (WorkerArgs) msg.obj;
.............
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;
.........
onQueryComplete由子类自行实现
protected void onQueryComplete(int token, Object cookie, Cursor cursor)
// Empty
至此AsyncQueryHandler的工作流程分析完毕。
容易看出,AsyncQueryHandler通过Handler机制,将ContentProvider对应的CRUD操作放到一个单独的子线程中执行,
当操作结束获取到结果后,再通过消息的方式传递给调用AsyncQueryHandler的线程。
它提供了一种将并发访问变为顺序异步访问的思路。
不过AsyncQueryHandler静态持有了一个HandlerThread,
且没有提供方法来释放该HandlerThread,
因此实际使用时可能需要自己仿照来重写一下。
最后盗图一张,给一下AsyncQueryHandler的原理图:
以上是关于Android O: AsyncQueryHandler分析的主要内容,如果未能解决你的问题,请参考以下文章
android O Error inflating class android.webkit.WebView
Android O中不会调用具有签名权限的Android隐式BroadcastReceiver
一起看 I/O | Android 13 Beta 2 现已发布