Android通信机制--Handler
Android通信机制–Handler
Handler机制大概是android开发过程中最常遇到的通信机制,简单说就是Looper从消息队列中不断去除消息进行处理。Handler通信中最核心的组件应该就是Handler,Looper,MessageQueue,Message了,这几个组件是如何构成消息的循环呢,我们先自己写个demo看看。
private Handler mHandler;
private void handlerDemo() {
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 100) {
Log.d(TAG, "handler self");
}
}
};
Looper.loop();
}
}).start();
}
发送消息的代码如下:
mHandler.sendEmptyMessage(100);
这就是Handler的基本用法,接下来我们分析下这其中的原理。通过代码可以知道,最重要的应该是Looper.prepare()
和Looper.loop()
这两个函数了。这两个函数内部是如何实现的呢?看下Looper.prepare()
:
public static void prepare() {
prepare(true);
}
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));
}
可以发现最终调用到了prepare(boolean quitAllowed)
中,继续发现新建了一个Looper并赋值给了一个ThreadLocal类型的变量sThreadLocal
,看到这里可以发现,调用Looper.prepare()
函数其实就是给当前的Thread设置了一个Looper
类型的变量,而且每个线程只能设置一次。
接下来看下new Looper(quitAllowed)
内部实现了什么逻辑。
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
终于看到MessageQueue了,这个quitAllowed
表示消息队列是否可以退出。可以发现Looper的构造函数新建了一个消息队列MessageQueue以及记录了当前的线程。
接下来就是消息循环了,消息循环从Looper.loop
函数开始。
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
......
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
......
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
......
msg.recycleUnchecked();
}
}
代码已经非常清晰了,调用loop()
函数后,首先判断当前是否已经调用prepare()
函数,如果已经调用,则进入for循环,不断去除消息队列中的消息。如果消息不为空,则调用msg.target.dispatchMessage(msg)
函数进行处理,msg.target
其实就是发送这个消息的handler,调用dispatchMessage
函数对消息进行处理。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
以上就是handler, Looper, Message三个组件是如何实现消息处理的。可能会有疑问,在这个位置使用Handler机制时调用了Looper.prepare和Looper.loop函数,但是为什么我们自己在Activity中可以直接新建Handler并进行消息处理呢。想想感觉应该在哪个位置调用这两个函数。
扒扒ActivityThread
的源码,你就会恍然大悟:
public static void main(String[] args) {
......
Looper.prepareMainLooper();
......
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
终于发现了,是不是很明了。
上一篇: 状态压缩