// 字段 /* * Set this flag to true to detect anonymous, local or member classes * that extend this Handler class and that are not static. These kind * of classes can potentially create leaks. * 非static的匿名内部类、局部变量或成员变量都将可能造成内存泄漏 */ private static final boolean FIND_POTENTIAL_LEAKS = false; final Looper mLooper; // 持有对应Looper,获取对应queue final MessageQueue mQueue; // 持有对应的消息队列,进行消息入队操作 final Callback mCallback; // hook,非null 优先回调处理消息 final boolean mAsynchronous; // 是否异步消息标识 IMessenger mMessenger; // 作用进程间通信
// 构造函数 Handler持有对应线程的Looper,同时持有对应Looper的MessageQueue public Handler() { ... } public Handler(Callback) { ... } public Handler(Looper) { ... } public Handler(Looper,Callback) { ... } public Handler(boolean) { ... } public Handler(Callback,boolean) { ... } public Handler(Looper,Callback,boolean) { ... }
// post方法,针对不同执行时间的Runnable的方法,最终Runnable转为Message,调用发消息方法插入队列 public final boolean post(Runnable r){ ... } public final boolean postAtFrontOfQueuepo(Runnable r){ ... } public final boolean postAtTime(Runnable r,long uptimeMillis){ ... } public final boolean postAtTime(Runnable r,Object token,long uptimeMillis){ ... } public final boolean postDelayed(Runnable r,long delayMillis){ ... }
// sendMessage方法,内部实现就是将Message入MessageQueue public final boolean sendMessage(Message msg){ ... } public final boolean sendEmptyMessage(int what){ ... } public final boolean sendEmptyMessageDelayed(int what, long delayMillis){ ... } public final boolean sendMessageDelayed(Message msg, long delayMillis){ ... } ...
// 定义一个可以发送给 Handler 的消息,包含描述和任意数据对象。消息对象有两个额外的 int 字段和一个 object 字段,这可以满足大部分场景的需求了。 // 推荐通过Message.obtain()构建Message而不是直接new,里面维护了默认50大小的链表Message的sPool public final class Message implements Parcelable { public int what; // 消息标识 public Object obj; // 消息数据存储,用于非bundle传输 // Flag标识(是否使用、是否异步消息) /*package*/ static final int FLAG_IN_USE = 1 << 0; /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1; /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE; /*package*/ int flags; /*package*/ long when; // 执行时间 /*package*/ Bundle data; // 非obj传输情况 /*package*/ Handler target; // 发送的Handler /*package*/ Runnable callback; / // sometimes we store linked lists of these things /*package*/ Message next; // Message单链表指向
private static final Object sPoolSync = new Object(); private static Message sPool; // Message 链表池 private static int sPoolSize = 0; private static final int MAX_POOL_SIZE = 50; private static boolean gCheckRecycle = true; // 回收标识
// 各种Message构建方法 public static Message obtain(Handler h, int what, int arg1, int arg2) { ... }
// 扮演消息循环角色,从MessageQueue取消息,有就执行,无则阻塞等待 public final class Looper { // 重要字段 // ThreadLocal缓存,实现各线程持有各自Looper对象。参考https://www.jianshu.com/p/8a7fe7d592f8 static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static Looper sMainLooper; // 持有主线程Looper,便于其它线程交互
final MessageQueue mQueue; // Looper对应的MessageQueue final Thread mThread; // Looper对应当前线程
// 构造函数私有,必须通过prepare方法来构建 private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); } // 构建Looper,通过ThreadLocal维护Looper(各线程对应一个Looper) private static void prepare(boolean quitAllowed) { // 主线程消息轮训不允许退出,一直循环处理 // 子线程消息轮训可以退出 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } // 主线程构建Looper方法(ActivityThread调用) public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); // 此处缓存主线程Looper,便于后续与主线程的交互 } }
// 最重要的 loop 方法,消息轮训实现 (部分关键代码) public static void loop() { final Looper me = myLooper(); // 获取当前线程对应的loop final MessageQueue queue = me.mQueue; for (;;) { // 循环去消息 (MessageQueue取过程可能阻塞) Message msg = queue.next(); // might block (参考MessageQueue next方法) if (msg == null) { return; } msg.target.dispatchMessage(msg);// 派发消息到对应Handler msg.recycleUnchecked(); // 释放message } }
// Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout. private boolean mBlocked; // 表明next方法是否block 当调用JNI pollOnce方法
// The next barrier token. // Barriers are indicated by messages with a null target whose arg1 field carries the token. private int mNextBarrierToken; // JNI 方法 private native static long nativeInit(); ......
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { int result = 0; for (;;) { ... result = pollInner(timeoutMillis); } }
int Looper::pollInner(int timeoutMillis) { ... // Poll. int result = POLL_WAKE; mResponses.clear(); mResponseIndex = 0;