您的位置:首页 > 产品设计 > UI/UE

AsyncQueryHandler学习

2012-03-07 15:07 405 查看
 学习这个类之前,需要先理解几个知识点:
1. Handler与Thread,Looper的关系

2. HandlerThread的作用

3. ThreadLocal类的作用
 

Handler 主要是用来发送(sendMessage)和处理消息(handleMessage),但是发送了消息后,消息是怎么传递的呢?这就是Looper(消息泵)的作用了,每个Handler中都会有一个Looper对象,如果在创建Handler的时候不指定,系统就会默认将当前线程的Looper绑定到Handler上,Looper对象中维护者一个消息队列,Hander 发送的消息都会存储到这个消息队列中,Looper不断的遍历这个消息队列,取出消息,交给handleMessage方法处理。Looper属于哪个线程,hadleMessage方法就会在那个线程中执行。

HandlerThread继承Thread,不但能提供异步处理,Handler处理消息的方法也会在这个线程中执行,他最要的作用就是提供了一个新线程。API解释如下:

Handy class for starting a new thread that has a looper.

ThreadLocal类主要是用来多个模块共享变量用的,但是不同线程之间的变量的值却不相同。即同一线程内,不同模块获取的对象(ThreadLocal类的实例)是同一个。

AsyncQueryHandler的工作机制是什么?

      

AsyncQueryHandler 继承了Handler对象,但是他提供的构造方法中却没有Looper参数,也就是说他和他所在的当前线程绑定。
AsyncQueryHandler源码:

    final WeakReference<ContentResolver> mResolver;

    private static Looper sLooper = null;

    private Handler mWorkerThreadHandler;  

    public AsyncQueryHandler(ContentResolver cr) {

        super();

        mResolver = new WeakReference<ContentResolver>(cr);//ContentResolver的弱引用,操作相关数据

        //允许访问控制,同步执行

        synchronized (AsyncQueryHandler.class) {

            if (sLooper == null) {

                //提供一个新线程

                HandlerThread thread = new HandlerThread("AsyncQueryWorker");

                thread.start();

                //start()方法必须被调用,否则通过getLooper方法得到的looper对象是空的。通过调用start方法,就会去执行该线程的run方法,

                sLooper = thread.getLooper();

            }

        }

        mWorkerThreadHandler = createHandler(sLooper);

    }

    protected Handler createHandler(Looper looper) {

        return new WorkerHandler(looper);

    }

AsyncQueryHandler内部有一个Hhandler对象,叫mWorkerHandler,他和一个HandlerThread绑定,mWorkerHandler负责将打包好的消息发送,并且处理,并将结果作为消息发送给AsyncQueryHandler。他是怎么发送的?AsyncQueryHandler内部有一个WorkerArgs完美类,他封装了startAsyncQuery等方法的参数,并且通过这行代码(红色部分)

    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 args = new WorkerArgs();
        args.handler = this;
        args.uri = uri;
        args.projection = projection;
        args.selection = selection;
        args.selectionArgs = selectionArgs;
        args.orderBy = orderBy;
        args.cookie = cookie;
       
msg.obj = args;

       
mWorkerThreadHandler.sendMessage(msg);
    }
将当前Handler封装进去,发送到HandlerThread中去,HandlerThread绑定的mWorkerHandler,mWorkerHandler负责将打包好的消息发送,并且处理完消息得到结果后,args.handler将结构发送给自己进行处理。(这就是线程间的通信了)。mWorkerHandler和一个子线程绑定(HanderThread),能够处理比较耗时的操作,AsyncQueryHandler提供异步处理。

   

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;

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息