-
Handle同步屏障机制
-
Handler的锁相关问题
-
Handler中的同步方法
- Handler在系统以及第三方框架的一些应用
-
HandlerThread
-
IntentService
-
如何打造一个不崩溃的APP
-
Glide中的运用
Handler的源码和常见问题的解答
下面来看一下官方对其的定义:
A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue.
Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler it is bound to a Looper.
It will deliver messages and runnables to that Looper’s message queue and execute them on that Looper’s thread.
大意就是Handler允许你发送Message/Runnable到线程的消息队列(MessageQueue)中,每个Handler实例和一个线程以及那个线程的消息队列相关联。当你创建一个Handler时应该和一个Looper进行绑定(主线程默认已经创建Looper了,子线程需要自己创建Looper),它向Looper的对应的消息队列传送Message/Runnable同时在那个Looper所在线程处理对应的Message/Runnable。下面这张图就是Handler的工作流程
Handler工作流程图
可以看到在Thread中,Looper的这个传送带其实就一个死循环,它不断的从消息队列MessageQueue中不断的取消息,最后交给Handler.dispatchMessage进行消息的分发,而Handler.sendXXX
,Handler.postXXX
这些方法把消息发送到消息队列中MessageQueue,整个模式其实就是一个生产者-消费者模式,源源不断的生产消息,处理消息,没有消息时进行休眠。MessageQueue是一个由单链表构成的优先级队列(取的都是头部,所以说是队列)。
前面说过,当你创建一个Handler时应该和一个Looper进行绑定(绑定也可以理解为创建,主线程默认已经创建Looper了,子线程需要自己创建Looper),因此我们先来看看主线程中是如何处理的:
//ActivityThread.java
public static void main(String[] args) {
···
Looper.prepareMainLooper();
···
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, “ActivityThread”));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException(“Main thread loop unexpectedly exited”);
}
可以看到在ActivityThread中的main方法中,我们先调用了Looper.prepareMainLooper()
方法,然后获取当前线程的Handler,最后调用Looper.loop()。先来看一下Looper.prepareMainLooper()
方法
//Looper.java
/**
-
Initialize the current thread as a looper, marking it as an
-
application’s main looper. The main looper for your application
-
is created by the Android environment, so you should never need
-
to call this function yourself. See also: {@link #prepare()}
*/
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException(“The main Looper has already been prepared.”);
}
sMainLooper = myLooper();
}
}
//prepare
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.prepareMainLooper()
方法中创建了当前线程的Looper,同时将Looper实例存放到线程局部变量sThreadLocal(ThreadLocal)中,也就是每个线程有自己的Looper。在创建Looper的时候也创建了该线程的消息队列,可以看到prepareMainLooper会判断sMainLooper是否有值,如果调用多次,就会抛出异常,所以也就是说主线程的Looper和MessageQueue只会有一个。同理子线程中调用Looper.prepare()
时,会调用prepare(true)
方法,如果多次调用,也会抛出每个线程只能由一个Looper的异常,总结起来就是每个线程中只有一个Looper和MessageQueue。
//Looper.java
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
再来看看主线程sMainThreadHandler = thread.getHandler()
,getHandler获取到的实际上就是mH这个Handler。
//ActivityThread.java
final H mH = new H();
@UnsupportedAppUsage
final Handler getHandler() {
return mH;
}
mH这个Handler是ActivityThread的内部类,通过查看handMessage方法,可以看到这个Handler处理四大组件,Application等的一些消息,比如创建Service,绑定Service的一些消息。
//ActivityThread.java
class H extends Handler {
···
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATIO