前言:由于Android系统本身决定了其自身的单线程模型结构。在日常的开发过程中,我们又不能把所有的工作都交给主线程去处理(会造成UI卡顿现象)。因此,适当的创建子线程去处理一些耗时任务是非常关键的。同时Android中非UI线程不能对UI组件进行操作,因此,熟练的掌握并应用线程间消息通信是很有必要的。接下来,我们从Android线程间通信机制和Android消息机制两个方面对以上内容进行介绍。
一.Android线程间通信机制
Android的线程间通信主要是在非UI线程对UI线程的消息传递,并且修改UI界面的操作。Android中常见的子线程更新UI的方式:
- handler.post(Runnable r)
- runOnUiThread(Runnable r)
- view.post(Runnable r)
- Handler+Message+MessageQueue+Looper
接下来我们依次看一下这几种调用方法的内部实现原理。
- handler.post(Runnable r)内部实现原理:
//Handler.post()方法:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
//Handler.sendMessageDelayed()方法:
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
//Handler.sendMessageAtTime()方法:
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
调用链:Handler.post->sendMessageDelayed->sendMessageAtTime
从上面的调用链可以看出,Handler.post方法最终调用了Handler.sendMessageAtTime方法,而通过sendMessageAtTime的实现逻辑可以看出,最终还是通过enqueueMessage方法将Message插入到消息队列,进行轮询处理。因此,底层还是Handler消息机制。
- runOnUiThread(Runnable r)内部实现原理:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}