首先需要先理清 Handler、MessageQueue、Looper 之间的关系。
我们使用Handler的时候(UI主线程)一般是通过以下两种方法去创建一个Handler实例
1. 最常用的方法:方法1
Handler mHandler =new Handler(){
@override
public void handleMessage(Message msg){
//To Do Something
}
}
mHandler.sendMessage(msg);//发送消息
去看一下Handler的无参构造方法是怎么创建Handler实例的
/**
* Default constructor associates this handler with the {@link Looper} for the
* current thread.
*
* If this thread does not have a looper, this handler won't be able to receive messages
* so an exception is thrown.
*/
public Handler() {
this(null, false);
}
无参构造方法里调用了另外一个构造方法,继续看下面的源码
/**
* Use the {@link Looper} for the current thread with the specified callback interface
* and set whether the handler should be asynchronous.
*
* Handlers are synchronous by default unless this constructor is used to make
* one that is strictly asynchronous.
*
* Asynchronous messages represent interrupts or events that do not require global ordering
* with respect to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
*
* @param callback The callback interface in which to handle messages, or null.
* @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
* each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
*
* @hide
*/
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 " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
重点看下面两句
mQueue = mLooper.mQueue;//将Looper的mQueue赋值给mHandler的 mQueue
在Handler的构造方法里面直接通过Looper的myLooper()方法初始化自己的mLooper,我们进入该方法
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
//下面是Looper中的静态变量 sThreadLocal 的定义
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
通过myLooper()方法的注释也可以知道,该方法返回的是当前线程的 Looper (注意:一个线程对应唯一的一个Looper)
但是怎么来获取当前的线程呢,进入ThreadLocal的get()方法就知道了
/**
* Returns the value in the current thread's copy of this
* thread-local variable. If the variable has no value for the
* current thread, it is first initialized to the value returned
* by an invocation of the {@link #initialValue} method.
*
* @return the current thread's value of this thread-local
*/
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();
}
现在我们应该明白了当我们通过方法1创建一个Handler实例的时候,在Handler的构造方法里会为我们获取当前线程的
Looper,并且将该Looper的MessageQueue对象的引用mQueue赋值给Handler的mQueue。所以我们通过Handler的se-
ndMessage()方法发送消息的时候自然也就发送到了该Handler所在线程的Looper所管理的MessageQueue消息队列中。
所以下面这句代码就是发送到了mHandler所在线程(UI线程)的Looper所管理的MessageQueue队列中
mHandler.sendMessage(msg);
2. 还有一种使用Handler的方法:方法2
这里我们采用了 IntentService 中的例子
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
重点关注以下代码:
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
在IntentService中自定义了一个Handler ServiceHandler ,在 new 一个Handler实例的时候,传入了一个参数mServiceLooper
这个Looper是哪里来的呢,代码里是通过HandlerThread的getLooper()方法获取,如果你去看HandlerThread的源码,就会发
现它其实也是通过Looper的myLooper()方法获取到的 HandlerThread 所在线程所对应的那个Looper。
ServiceHandler的构造方法直接调用了父类的构造方法:super(looper),也就是 Handler 的构造方法
接下来我们再去看一下 Handler 的另一个构造函数
/**
* Use the provided {@link Looper} instead of the default one.
*
* @param looper The looper, must not be null.
*/
public Handler(Looper looper) {
this(looper, null, false);
}
可以看到,该构造方法又调用了Handler的另一个构造方法:
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
这里依然是和方法1中的构造方法一样的操作,将传入的serviceLooper 最终赋值给了 Handler的mLooper(同时也是子类ServiceHandler的mLooper),再将该Looper对应的 mQueue 赋值给了 Handler 的mQueue(同时也是子类ServiceHandler的mQueue)