消息机制相关类的介绍
Handler
Handler作为一个消息处理的类,负责消息的发送和消息的执行,消息的发送又包含即时的和延时的。应用场景包含多线程间通信。Handler的运转以及要支持多线程间通信,还需要Looper类。
Looper
Looper主要从列表中获取消息,并且处理消息。Looper提供了一些静态方法(prepare()、myLooper()、myQueue()、loop()等),这些静态方法都使用了一个静态成员sThreadLocal(ThreadLocal类),sThreadLocal存储了与线程对应的Looper的对象。Looper类中组合了一个MessageQueue类。而Looper取消息的来源正是MessageQueue。
MessageQueue
MesssageQueue类中维护一个消息队列(由链表实现),MessageQueue不仅组合在Looper中,也聚合在Handler中。它向Handler提供了把消息入队列的接口,向Looper提供了把消息从队列取出的接口。
HandlerThread
HandlerThread is-a Thread,并且主要职责是在run方法中创建Looper对象和执行Looper的loop循环(通过调用Looper的静态方法)。这样就可以想象一个多线程的环境下,线程A通过Handler发送消息,Handler把消息传给MessageQueue入队列;线程B通过Looper的loop循环,从MessageQueue中取出并处理该消息。
Message
上面一直提的消息,其实是Message类,它里边包含了消息值(what),以及其它一些消息信息(arg1、arg2、obj)。Message类中的字段next,是为了实现MessageQueue中的消息链表。Message类中target字段是Handler类,引用了外层的Handler对象,它的作用是,当Looper取出消息后,要处理它,其实就是调用消息中的target的dispatchMessage方法。如下代码,摘自于Looper的静态方法loop中的一处处理消息的代码。1
2
3
4
5
6
7
8
9
10final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
final long end;
try {
msg.target.dispatchMessage(msg);
end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
图示
为了方便理解,用StarUML设计了一张类图和一张时序图。
进阶
epoll
关于epoll的介绍,可以看这里https://segmentfault.com/a/1190000003063859