目录
1、背景
2、简介
3、使用
4、源码详解
4.1、第一步:Looper.prepare()
4.2、第二步:new Handler()
4.3、第三步:Looper.loop()
4.4、第四步:发送消息
5、全部代码
5.1、Handler类
5.2、Looper类
5.3、Message类
5.4、MessageQueue类
1、我们都知道Android只允许在主线程中进行UI的更新操作,那么为什么不允许在子线程中更新UI呢?
答:这是因为Android的UI空间是线程不安全的,如果多线程并发访问UI,可能导致UI控件处于一个不可预期的状态。
2、那么为什么不给UI控件添加锁机制呢?
答:首先加上锁会让UI的更新逻辑变得复杂;其次锁机制会降低更新UI的效率。
稍微了解过Handler原理的人,都知道Handler的实现其实和 Message、MessageQueue、Looper这三个类共同完成的。
- Message :信息对象的实体类;
- MessageQueue:存储Message对象的类,内部使用单链表的信息存储多个Message对象。
- Looper :会开启个死循环,不断地从MessageQueue中的单链表中遍历Message对象,然后将Message对象分发给Handler处理。
- Handler:作用就是将Message对象放入MessageQueue的单链表中,然后处理从Looper获取到的Message对象。
当我们在主线程使用Handler的时候,一般都直接new 一个Handler就可以正常使用了。但是正常启用一个Handler流程需要调用Looper的prepare()和loop()方法。如下的代码:
那么主线程中的Handler为什么不需要调用这两个方法呢?
答:这是因为在主线程,也就是ActivityThread线程中,提前为我们调用了这两个方法。
接下来的内容,是我在源码的基础上,简化了代码,自己实现的简易版Handler,方法名与源码都是对应的。如果有兴趣看源码可以对照这看,这样理解起来比较容易。
prepare()的源码很简单,他就是利用ThreadLocal将我们new出来的Looper对象保存到了当前的所在的线程中。
ThreadLocal.ThreadLocalMap内部其实是一个数组保存着Looper。ThreadLocalMap是自定义的哈希映射,仅适用于维护线程局部值。 没有操作导出到ThreadLocal类之外。 该类是包私有的,以允许声明Thread类中的字段。
这样在我们new Thread("handler线程:")线程就有了Looper对象。
new Handler() 的实现其实很简单,就是实现了Callback接口来为后面处理消息做准备,而这里同时保存了Looper中的MessageQueue对象,这个对象在Looper.prepare()的时候,会new出来。
注意:在我们new Handler()的时候,如果没有提前调用Looper.prepare()方法,会报异常。
Looper.loop()方法的作用就是开启一个死循环,不断地从MesssageQueue的单链表中遍历下一个Message对象,然后将这个Message对象发送给Handler来处理。
1、loop()中 首先通过ThreadLocal.get()来获取我们接受消息线程的Looper对象;
2、然后得到这个Looper对象中的MessageQueue对象;
3、然后用这个MessageQueue对象调用自身的next方法,遍历单链表中的Message对象;
4、将获取到的Message对象,传递给Handler的dispatchMessage()方法来处理。「Message.target保存着的就是发送这个Message的Handler对象,这个会在第四步说明」
5、这样我们的Message对象就回调回我们new Handler时候的 handleMessage()函数中了。
我们完成上面的三步之后,发现我们的Looper在不断地从一个空的MessageQueue的单链表中,遍历Message对象。
这时候,就需要我们来发送一条Message来让Handler处理。
1、我们new 一个名字叫“Message线程”的线程,然后在里边通过我们前面new 的Handler对象发送了一条消息。
2、sendMessage()方法最后会调用MessageQueue对象的enqueueMessage()方法,将我们的Message对象插入到单链表中
3、这样我们的Looper.loop()就能获取到Message对象,这样我们的Handler的handleMessage()就能回调到Message对象。
注意:下面白色框中,就是将Handler对象保存在Message中的步骤。
github地址
运行代码:
public class TestMyHandler {
private static Handler mHandler;
public static void main(String[] args) throws InterruptedException {
initHandler();
Thread.sleep(3000);
sendMessage();
}
private static void initHandler() {
new Thread("Handler线程") {
@Override
public void run() {
super.run();
Looper.prepare();
mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1000) {
String result = (String) msg.obj;
showLog("---接受--->: " + result);
}
return false;
}
}, false);
Looper.loop();
}
}.start();
}
private static void showLog(String msg) {
System.out.println(Thread.currentThread().getName() + ": " + msg);
}
private static void sendMessage() {
new Thread("Message线程") {
@Override
public void run() {
Message msg = new Message();
msg.what = 1000;
msg.obj = Thread.currentThread().getName() + ": 你好啊";
Message msg1 = new Message();
msg1.what = 1000;
msg1.obj = Thread.currentThread().getName() + ": 你好啊1";
mHandler.sendMessage(msg);
mHandler.sendMessage(msg1);
}
}.start();
}
}
//输出结果
Handler线程: ---接受--->: Message线程: 你好啊
Handler线程: ---接受--->: Message线程: 你好啊1
public class Handler {
private final MessageQueue mQueue;
private final Callback mCallback;
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*/
public interface Callback {
boolean handleMessage(Message msg);
}
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
Looper 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;
}
/**
* 发送消息
*/
public final boolean sendMessage(Message msg) {
MessageQueue queue = mQueue;
if (queue == null) {
return false;
}
return enqueueMessage(queue, msg);
}
private boolean enqueueMessage(MessageQueue queue, Message msg) {
msg.target = this;
return queue.enqueueMessage(msg, 0);
}
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run();
}
}
class Looper {
static final ThreadLocal sThreadLocal = new ThreadLocal<>();
/**
* 当前线程
*/
private final Thread mThread;
MessageQueue mQueue;
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
static void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(true));
}
static Looper myLooper() {
return sThreadLocal.get();
}
static void loop() {
Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
MessageQueue queue = me.mQueue;
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
return;
}
try {
msg.target.dispatchMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
msg.recycleUnchecked();
}
}
}
public class Message {
int what;
Object obj;
long when;
Handler target;
private boolean isUse;
Runnable callback;
/**
* MessageQueue 以单链表的形式来存储Message对象
*/
Message next;
void markInUse() {
isUse = true;
}
public Runnable getCallback() {
return callback;
}
public Message setCallback(Runnable r) {
callback = r;
return this;
}
void recycleUnchecked() {
what = 0;
obj = null;
when = 0;
target = null;
callback = null;
}
}
class MessageQueue {
private Message mMessages;
MessageQueue(boolean quitAllowed) {
}
/**
* 将Message 对象插入到单链表中
*/
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
synchronized (this) {
msg.markInUse();
msg.when = when;
Message p = mMessages;
/*
* 1、下面的操作是为了将单链表中的所有Message按照 延迟发送的时间排序
* 2、新添加的msg需要插入到单链表中合适的位置
*/
if (p == null || when == 0 || when < p.when) {
// 将这个msg放在单链表的头部
msg.next = p;
mMessages = msg;
} else {
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
}
return true;
}
Message next() {
for (;;) {
synchronized (this) {
Message prevMsg = null;
Message msg = mMessages;
/*
* 如果Message 没有target就抛弃这些Message
*/
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null);
}
if (msg != null) {
// Got a message.
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
msg.markInUse();
return msg;
}
}
}
}
}