`
wsqwsq000
  • 浏览: 675477 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

AsyncQueryHandler

 
阅读更多

AsyncQueryHandler研究

android 2010-11-09 00:29:52 阅读163 评论0   字号: 订阅

今天晚上研究了一下啊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类主要是用来多个模块共享变量用的,但是不同线程之间的变量的值却不相同。

image

说明1:对象a,对象b比如说是某个类的实例对象,在模块A,B,C中共享对象a,还有对象b,在线程A中,模块A中设置a的值,在模块B,C中取出a的值,三个模块操作的是同一个值,但是对象a和对象b分别属于两个线程,他们是不同的。

AsyncQueryHandler的工作机制是什么?

AsyncQueryHandler继承了Handler对象,但是他提供的构造方法中却没有Looper参数,也就是说他和他所在的当前线程绑定,AsyncQueryHandler内部有一个Hhandler对象,叫mWorkerHandler,他和一个HandlerThread绑定,mWorkerHandler负责将打包好的消息发送,并且处理,并将结果作为消息发送给AsyncQueryHandler。他是怎么发送的?AsyncQueryHandler内部有一个WorkerArgs完美类,他封装了startAsyncQuery等方法的参数,并且通过这行代码

WorkerArgs args = new WorkerArgs();
       args.handler = this;

将当前Handler封装进去,发送到HandlerThread中去,mWorkerHandler处理完消息得到结果后,args.handler将结构发送给自己进行处理。(这就是线程间的通信了)

mWorkerHandler和一个子线程绑定,能够处理比较耗时的操作,AsyncQueryHandler提供异步处理。

 

总结:

Handler有两个作用,Handler用在一个线程中,就是实现异步操作。用在不同的线程之间,那就是异步操作加线程间通信。

补充:

HandlerThread:

先看他的类描述:Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

这是一个包含了Looper对象的线程,这个looper可以用来创建Handler对象,记住:start()方法必须被调用,否则通过getLooper方法得到的looper对象是空的。通过调用start方法,就会去执行该线程的run方法, public void run() {

        mTid = Process.myTid();

        Looper.prepare();//创建一个Looper实例,并且存储在ThreadLocal中,ThreadLocal中维护一个HashMap,键是线程号

        synchronized (this) {

            mLooper = Looper.myLooper();//得到当前线程的Looper,就是刚才perpare方法中创建并存储的那个Looper实例

            Process.setThreadPriority(mPriority);

            notifyAll();

        }

        onLooperPrepared();

        Looper.loop();//开始轮询

        mTid = -1;

    }

 

 public static final void prepare() {

        if (sThreadLocal.get() != null) {

            throw new RuntimeException("Only one Looper may be created per thread");

        }

        sThreadLocal.set(new Looper());

    }

 

 public static final Looper myLooper() {

        return (Looper)sThreadLocal.get();

    }

 

 

AsyncQueryHandler是如何提供onxxxComplete方法给用户,由用户自己实现的?

public abstract class AsyncQueryHandler extends Handler  他是一个抽象类

 

MessageQueue是不是一个任务队列?

是,他是一个优先级队列(可以通过ArrayList的排序来实现)。它内部自己维护一个ArrayLsit集合,用来存储Message消息,Message消息有三种,普通消息,按照先发送先执行的FIFO原则进行;高优先级的消息,这种消息会直接插在队列的最前面,立刻执行;还有一种定时消息,类似于定时任务,到时间才执行。

Looper是如何轮询MessageQueue的?

当在主线程中使用Handler的时候,不用指定Looper,因为在主线程开启的时候,就已经调用了Looper.loop()方法开始轮询了。

挡在子线程中使用Handler的时候,通过调用Looper的prepare方法创建存储Looper对象,还得调用Looper.loop()方法开启轮询。

当配合HandlerThread使用Handler的时候,HandlerThread的run方法中调用了Looper.loop()方法。

 

    public static final void loop() {

        Looper me = myLooper();

        MessageQueue queue = me.mQueue;

        while (true) {

            Message msg = queue.next(); // might block

            //if (!me.mRun) {

            //    break;

            //}

            if (msg != null) {

                if (msg.target == null) {

                    // No target is a magic identifier for the quit message.

                    return;

                }

                msg.target.dispatchMessage(msg);

                msg.recycle();

            }

        }

    }

Message消息实现了Parcelable接口
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics