zoukankan      html  css  js  c++  java
  • Android学习笔记_76_AsyncQueryHandler的应用

    研究AsyncQueryHandler这个类的时候遇到了几个重要的不清楚的知识点
    1. Handler与Thread,Looper的关系
    2. HandlerThread是干什么用的
    3. ThreadLocal类是干什么用的
    Handler 主要是用来发送和处理消息,但是发送了消息后,消息是怎么传递的呢?这就是Looper的作用了,每个Handler中都会有一个Looper对象,如果在创建Handler的时候不指定,系统就会默认将当前线程的Looper绑定到Handler上,Looper对象中维护者一个消息队列,Hander 发送的消息都会存储到这个消息队列中,Looper不断的遍历这个消息队列,取出消息,交给handleMessage方法处理。Looper属于哪个线程,hadleMessage方法就会在那个线程中执行。
    
           HandlerThread不但能提供异步处理,Handler处理消息的方法也会在这个线程中执行,他最要的作用就是提供了一个线程。(这个类还有待研究)
     ThreadLocal类主要是用来多个模块共享变量用的,但是不同线程之间的变量的值却不相同。
    
    AsyncQueryHandler的工作机制是什么?
           AsyncQueryHandler 继承了Handler对象,但是他提供的构造方法中却没有Looper参数,也就是说他和他所在的当前线程绑定,AsyncQueryHandler内部有一个Hhandler对象,叫mWorkerHandler,他和一个HandlerThread绑定,mWorkerHandler负责将打包好的消息发送,并且处理,并将结果作为消息发送给AsyncQueryHandler。他是怎么发送的?AsyncQueryHandler内部有一个 WorkerArgs完美类,他封装了startAsyncQuery等方法的参数,并且通过这行代码
    java代码:
    WorkerArgs args = new WorkerArgs();
    args.handler = this;
    复制代码
    
           将当前Handler封装进去,发送到HandlerThread中去,mWorkerHandler处理完消息得到结果后,args.handler将结构发送给自己进行处理。(这就是线程间的通信了)
    
           mWorkerHandler和一个子线程绑定,能够处理比较耗时的操作,AsyncQueryHandler提供异步处理。
    
    1,若我们不用AsyncQueryHandler,直接在UI 线程调用ContentResolve去操作数据库比如查询,若你的数据库的数据很少还好,若很多,就会出现ANR了。一般解决ANR,就是开thread去解决。我在去年做案子的时候,就遇到这样的情况,数据太多了,我不得不开thread去查询,那开了Thread就得通过Handler来和UI线程交互,让UI线程知道何时查询完毕,可以更新UI将查询的结果表现出来。 
    2,若我们用AsyncQueryHandler,AsyncQueryHandler它就会主动地帮你开了Thread来避免ANR,并且它是继承于Handler,所以就可以通过onCompleteQuery来通知UI线程已经查询(删除...)完了。 

       短信操作的异步类,在执行查下短信时,可以先调用srartQuery方法执行异步查询,然后在调用onQueryComplete方法实现数据的更新。

    mQueryHandler.startQuery(i, null, uri, null, null, null, null);
    private final class QueryHandler extends AsyncQueryHandler{
    
            public QueryHandler(ContentResolver cr) {
                super(cr);
                // TODO Auto-generated constructor stub
            }
            
            @Override
            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
                // TODO Auto-generated method stub
                super.onQueryComplete(token, cookie, cursor);
                if(cursor.getCount() > 0){
                    int count = cursor.getCount();
                    sizeMap.put(token, count);
                    mAdapter.notifyDataSetChanged();
                }
                cursor.close();
            }
        }
  • 相关阅读:
    Jackson学习资料
    servlet/filter/listener/interceptor区别与联系
    JDBC、JTA、Spring的事务管理
    hibernate 的SessionFactory的getCurrentSession 与 openSession() 的区别
    Spring MVC如何配置OpenSessionInViewInterceptor并结合Hibernate使用
    SpringMVC中使用Interceptor拦截器
    Hibernate条件查询
    Spring MVC之@RequestBody, @ResponseBody 详解
    Sping Environment为Null的原因和解决方法
    SpringMVC+Thymeleaf如何处理URL中的动态查询参数
  • 原文地址:https://www.cnblogs.com/lbangel/p/3728416.html
Copyright © 2011-2022 走看看