Looper和Handler类分析

一.  Looper

1. 如何使用Looper?

(1) 定义一个LooperThread.

class LooperThread extends Thread {
    public Handler mHandler;
    public void run() {
        Looper.prepare();    // 调用prepare();
        Looper.loop();         // 进入消息循环。

    }
}

(2) 应用程序中使用LooperThread:

{
   new LooperThread().start();     // 启动新线程,线程函数是run.
}

 

2. Looper.prepare()函数:   

 public static final void prepare() {
        if (sThreadLocal.get() != NULL) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());     // 构造一个Looper对象,设置到调用线程的局部变量(TLV)中,将Looper与线程绑定在一起。
    }

3. Looper的创建: 

private Looper() {
        mQueue = new MessageQueue();    // 构造一个消息队列。
        mRun = true;
        mThread = Thread.currentThread();        // 得到当前线程的Thread对象。
    }

由此可见, 在调用prepare线程中,为该线程设置了一个Looper对象,Looper对象内部封装了一个消息队列。

4. Looper.loop()的实现

public static final void loop() {
        Looper me = myLooper();       // myLooper()返回保存在调用线程TLV中的Looper对象。
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next();
            if (msg != NULL) {
                if (msg.target == NULL) {     // target类型是Handler类型,若为空,则表示需要退出消息循环。
                       return;
                }
                msg.target.dispatchMessage(msg);   // 调用该消息的handler, 交给它的dispatchMessage函数处理。
                msg.recycle;
            }
        }
    }

 

5. Looper,Message和Handler的关系:

    Looper中有一个Message队列, 存储待处理的message。

    Message中有一个Handler, 这个Handler用来处理message.

 

二.  Handler

1. Handler类包含了三个成员:

    final MessageQueue mQueue;    // 最终都会指向某个Looper的消息队列
    final Looper mLooper;           // 它的值有可能通过构造函数由外面传进来,有可能通过Looper.myLooper()函数获得调用线程的Looper。
    final Callback mCallback;   // 作为回调用。

 

2. Handler提供了一系列用于创建消息和插入消息队列的函数。如发送消息的函数:

 public final boolean sendMessage(Message msg) {
        return sendMeeageDelayed(msg, 0);
    }

    public final boolean sendMessageDelayed(Message msg, long delayMillis) {         // delayMillis是以当前时间为基础的相对时间
        if (delayMillis < 0) {
              delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);      // 调用sendMessageAtTime, 把当前时间算上。
    }
    public final boolean sendMessageAtTime(Message msg, long uptimeMillis)  {             // uptimeMillis是绝对时间,因此该函数处理的是绝对时间
        bool sent = false;
        if (mQueue != null) {
              msg.target = this;                                                       // 将target设为自己,因为Handler还封装了消息处理的接口。
              sent = mQueue.enqueueMessage(msg, uptimeMillis);
        }
        return sent;
    }

 

3. 处理消息的函数dispatchMessage()

public void dispatchMessage(Message msg) {
        if (msg.callback != null) {      // 如果Message本身有callback, 则直接交给Message的callback处理。
             handleCallback(msg);
        } else {
             if (mCallback != null) {        // 若本Handler设置了mCallback, 则交由它处理。
                 if (mCallback.handleMessage(msg)) {
                      return;
                 }
             }
              handleMessage(msg);      // 最后交给子类处理。
        }
    }

 

posted on 2015-03-14 15:59  Jackwen  阅读(354)  评论(0编辑  收藏  举报