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.     }  


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AsyncQueryHandler是一个用于实现异步操作数据库功能的抽象类。它继承自Handler类,并通过两个不同的Handler在主线程和异步线程中进行操作。在构造函数中,AsyncQueryHandler接收一个ContentResolver对象作为参数,并创建一个对ContentResolver的弱引用。同时,它还创建了一个名为"AsyncQueryWorker"的HandlerThread,并获取其Looper。接下来,AsyncQueryHandler通过createHandler方法创建了一个WorkerHandler,该Handler在异步线程中处理消息。\[1\] 在使用AsyncQueryHandler时,可以通过调用startQuery方法来发起查询操作。查询结果将通过WorkerHandler的handleMessage方法传递给AsyncQueryHandler的handleMessage方法。最后,可以在onDeleteComplete方法中处理删除操作的结果。\[2\] 总的来说,AsyncQueryHandler通过在主线程和异步线程中的两个Handler之间的消息传递,实现了异步访问数据库的功能。\[3\] #### 引用[.reference_title] - *1* *3* [AsyncQueryHandler详解及使用](https://blog.csdn.net/weixin_42193691/article/details/82469627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Android-AsyncQueryHandler 详解【整理】](https://blog.csdn.net/fanleiym/article/details/83783949)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值