Handler

2018-07-20  本文已影响0人  大冷月

Handler
MessageQueue
Looper

Handler

发送消息和处理消息

  • sendMessage(Message msg)
  • sengMessageDelayed(Message msg,long delayMills)
  • dispatchMessage(Message msg)
    1、msg.callback不为空则执行并结束,为空则进行下一步
    2、mCallback执行返回true则结束,false继续下一步
    3、handler的handleMessage方法执行
/**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

MessageQueue

链表,主要包含两个方法,插入和读取。对应的方法分别为enqueueMessage和next,enqueueMessage插入一条消息,next读取并移除一条消息。

  • enqueueMessage:
    遍历消息列表,插入到位置msg.when > pre.when && msg.when < next.when。详情查看enqueueMessage源码。
  • next:
    无限的循环,从消息列表取出消息,如果没有消息就会阻塞在这里。

Looper

轮询消息

  • prepare
  • loop
    一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回了null。
  • quit
    当Looper的quit方法被调用时,Looper会调用MessageQueue的quit或者quitSafely方法,通知消息列表退出。否则loop方法会无限循环下去。MessageQueue的next方法是一个阻塞方法,当没有消息时next方法会一直阻塞在那里,这也导致loop方法一直被阻塞在那里。如果MessageQueue的next方法返回Message,则loop会处理这条消息,msg.target.dispatchMessage(msg)。msg.target是发送消息的Handler,最终代码的执行是在创建Handler所使用的Looper中调用的,这样就成功的将代码逻辑切换到指定线程中执行了。

使用ThreadLocal来管理Looper,可以使每个线程有自己的一个Looper。

ThreadLocal:

ThreadLocal是一个线程内部的数据存储类

  • 通过它可以在指定的线程中存储数据.
  • 只有在指定的线程才可以获取到相应线程存储的数据。
    每个线程有一个ThreadLocalMap,里面存放着<ThreadLocal,Object>键值对,可以分析ThreadLocal的get方法
    1、先拿到当前线程
    2、拿到当前线程的ThreadLocalMap
    3、从ThreadLocalMap中取出key为当前ThreadLocal的值
    4、如果值为空则调用setInitialValue()方法获取默认值
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
上一篇 下一篇

猜你喜欢

热点阅读