Android AsyncQueryHandler

此为AsyncQueryHandler的构造方法

[java]  view plain copy
  1. public AsyncQueryHandler(ContentResolver cr) {  
  2.         super();  
  3.         mResolver = new WeakReference<ContentResolver>(cr);  
  4.         synchronized (AsyncQueryHandler.class) {  
  5.             if (sLooper == null) {  
  6.                 HandlerThread thread = new HandlerThread("AsyncQueryWorker");  
  7.                 thread.start();  
  8.      //需要注意的是此getLooper()方法在HandlerThread类中是同步等待获取run()方法中prepare()准备的线程相关的Looper对象,  
  9.     // 也就是说分线程准备好了looper以后,在此线程中才可以得到  
  10.                 sLooper = thread.getLooper();  
  11.             }  
  12.         }  
  13.         mWorkerThreadHandler = createHandler(sLooper);  
  14.     }  


在AsyncQueryHandler构造中new出来 的HandlerThread继承了Thread 在其的run方法中创建 了个Looper轮询器,并阻塞调用.loop方法在那不停的轮询这个内部开启的工作线程的队列.  在这内部开启的线程中获得了这个线程绑定的轮询器., 用这个轮询器创建了一个WorkerHandler的mWorkerThreadHandler变量的Handler ,

由于此Handler在创建时接收了这个开启的线程的轮询器 , 那这个Handler就相当于在这个线程中创建的,自然它的handeMessage方法将会运行在这个线程中执行,


这也就是这个AsyncQueryHandler的特别之处, 其中有两个handleMessage方法 , 要记住:AsyncQueryHandler的handleMessage方法是主线程中运行的, 而WorkerThreadHandler的handleMessage方法是在构造方法中创建的一个线程中执行的, 只不过它的代码被放到这个类中了. 为什么呢? 我看到这个handlerMessage方法的代码中用到了ContentResolver对象,此对象是从UI主线程中传过来的, 所以放在这不用传给那个开启的线程也是未尝不可的.

在这个handleMessage中最终是将执行的结果cursor通过Message回复到AsyncQueryHander这个类的handlerMessage中执行,在其中解析msg并根据event判断操作类型(CRUD)来执行AsyncQueryHandler的回调方法.

所以我们在主线程中实现这个AsyncQueryHandler类的时候可以选择性的重写这四个protected修饰的on….Complete完成方法来做一些数据操作完成后的操作.

 

整个异步查询的操作其时就是AsyncQueryHandler类内部的两个handleMessage之间交互的过程.

入口就是start开头的CRUD操作,在这些start方法中只是把参数用一个Message封装起来调用那个构造中创建的子线程的轮询器的Handler对象(mWorkerThreadHandler).的sendMessage()方法来发送的

WorkerHandler的handleMessage方法中收到解析执行这个用户封装的msg中的内容, 并将结果又返回给AsyncQueryHandler这个HandleMessage方法在其中回调用户实现的on…Complete方法完成数据的后续处理.


以下为部分源码

[java]  view plain copy
  1.  protected class WorkerHandler extends Handler {  
  2.         public WorkerHandler(Looper looper) {  
  3.             super(looper);  //看此处使用了looper  
  4.         }  
  5.     public void handleMessage(Message msg) {  
  6.             final ContentResolver resolver = mResolver.get();  
  7.             if (resolver == nullreturn;  
  8.             WorkerArgs args = (WorkerArgs) msg.obj;  
  9.             int token = msg.what;  
  10.             int event = msg.arg1;  
  11.             switch (event) {  
  12.                 case EVENT_ARG_QUERY:  
  13.                     Cursor cursor;  
  14.                    //..............CRUD操作  
  15. args.result = cursor;  
  16.             }  
  17.             Message reply = args.handler.obtainMessage(token);///回复msg  
  18.             reply.obj = args;  
  19.             reply.arg1 = msg.arg1;  
  20.             reply.sendToTarget();  //回复  
  21. =============  
  22. public void startQuery(int token, Object cookie, Uri uri,  
  23.             String[] projection, String selection, String[] selectionArgs,  
  24.             String orderBy) {  
  25.         // Use the token as what so cancelOperations works properly  
  26.         Message msg = mWorkerThreadHandler.obtainMessage(token);  
  27.         msg.arg1 = EVENT_ARG_QUERY;  
  28.         WorkerArgs args = new WorkerArgs();  
  29.         args.handler = this;  
  30.         args.uri = uri;  
  31.         args.projection = projection;  
  32.         args.selection = selection;  
  33.         args.selectionArgs = selectionArgs;  
  34.         args.orderBy = orderBy;  
  35.         args.cookie = cookie;  
  36.         msg.obj = args;  
  37.         mWorkerThreadHandler.sendMessage(msg);//此处是向开启的那个线程中的handler发送 消息  
  38. =====================  
  39. public class HandlerThread extends Thread {  
  40.   public void run() {  
  41.         mTid = Process.myTid();  
  42.         Looper.prepare();      //由于 不是在主线程中WorkerHandler中包含的这个Looper对象必须手动的调用prepare来准备好(另附:looper是线程本地化的)  
  43.         synchronized (this) {  
  44.             mLooper = Looper.myLooper();  //获得当前线程的轮询器  
  45.             notifyAll();  
  46.         }  
  47.         Process.setThreadPriority(mPriority);  
  48.         onLooperPrepared();  
  49.         Looper.loop();      ///阻塞 方法, 不断的从队列中取消息.  
  50.         mTid = -1;  
  51.     }  


如有理解错误和不准确的地方,还请一定要回复...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值