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

        }

    }

 

你可能感兴趣的:(Android学习)