本文章要感谢 Android异步消息处理机制完全解析,带你从源码的角度彻底理解, Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系。网上讲Handler机制的文章不少,总的来说内容相近。这两篇一篇是郭大神的,一篇是鸿洋大神的,质量都蛮高。感兴趣的读者可以去瞅一瞅。
1. 概述
异步请求一般需要这四样法宝Handler,Looper,MessageQueue,Message。他们之间的关系如图所示
Handler负责发送和处理消息,MessageQueue将Handler发送过来的消息以队列(其实是链表)的形式存储,Looper不断的从MessageQueue中获取Message并交由Handler处理。
Handler的功能主要是将一个任务执行在Handler被创建的线程,这一特性正好可以广泛使用在UI线程的更新上。要提Handler必须先提Looper,没办法博主很想从大家最熟悉的Handler切入,但是不提Looper,Handler都创建不了,所以按博主的知识学习习惯,还是得先弄懂Looper。
2. Looper
为什么不创建Looper,就没法创建Handler,先看Handler的构造函数
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
构造函数中先获取Looper对象,如果为空,则抛出异常。顺着看myLooper()的实现
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
从sThreadLocal对象中取出Looper,如果没有Looper存在自然就返回空。ThreadLocal是线程内部的一个存储类,在指定的线程中存储数据,详细的介绍可以参考《Android开发艺术探索》—Android的消息机制一章。
那Looper对象是在哪儿创建的呢?Looper中有两个关键的方法prepare()和loop(),先看prepare:
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");