Handler源码解析
数据通讯在开发中带来什么问题
Handler机制是消息管理机制,管理Android系统的所有事物,维持Android应用运行。
一、Handler简单使用
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
Log.d(TAG, "mHandler received message 0");
break;
default:
super.handleMessage(msg);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Message message = Message.obtain();
message.what = 0;
mHandler.sendMessage(message);
}
}).start();
}
二、Handler消息机制
1、Looper的初始化
主线程的Looper是在进程启动的时候启动的,入口函数是ActivityThread#main
public static void main(String[] args) {
//创建Looper, MessageQueue
Looper.prepareMainLooper();
......
//取出消息并处理
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Looper#prepareMainLooper – > Looper#prepare(boolean)
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
// 保证Looper的唯一性
throw new RuntimeException("Only one Looper may be created per thread");
}
// 创建Looper对象并放入ThreadLocal中
sThreadLocal.set(new Looper(quitAllowed));
}
Looper构造方法
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
-
问题1:Looper的构造为什么被私有?
便于管理,每个线程只允许创建一个Looper对象。 -
问题2:Looper和MessageQueue的唯一性?
MessageQueue是在创建Looper的时候创建的,通过final修饰;
ThreadLocal也是在Looper中创建的,且被static final
修饰;
Looper在prepare的时候,先通过sThreadLocal.get(),如果存在就抛异常,不允许线程再次创建Looper。再来看sThreadLocal#set,获取当前线程中的ThreadLocalMap,将ThreadLocal作为key,Looper对象作为value保存。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
2、Handler的创建
创建Handler时获取到与当前线程绑定的Looper对象,然后获取到MessageQueue,此时Handler就可以操作消息队列MessageQueue;
public Handler(Callback callback, boolean async) {
......
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
}
3、Handler消息发送流程
Handler#sendMessage --> Handler#enqueueMessage --> MessageQueue#enqueueMessage
在MessageQueue#enqueueMessage中,将Message插入到队列(单链表实现的优先级队列)中。
Handler#enqueueMessage
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.</