1、Handler
先来看下官方对Handler的描述
A Handler allows you to send and process {@link Message} and Runnable
objects associated with a thread's {@link 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 the thread /
message queue of the thread that is creating it -- from that point on,
it will deliver messages and runnables to that message queue and execute
them as they come out of the message queue.
翻译过来的大概意思:Handler允许你发送、执行与线程相关的Message和Runnable对象,每个Handler实例
关联到一个单独的线程和线程中的Message Queue。当创建Handler对象时,它被绑定到所在的线程、
MessageQueue --基于这点,Handler将会发送Message和Runnable到那个MessageQueue中,
并且在那个线程中执行Message和Runnable。
Handler主要有2个使用场景:
(1)计划在未来某个时间点执行Messages和Runnable;
(2)在别的线程中插入一个想要执行的Action;
Handler的使用方式:
//使用Handler执行任务Runnable
//在主线程中构造handler对象,然后在其他线程中调用handler.post方法,则Runnable将会在主线程中被执行
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
//do somethings
}
});
handler.postDelayed(new Runnable() {
@Override
public void run() {
//do somethings
}
}, 1000);
//在主线程中构造Handler对象,在其他线程在发送Message,则Message将会在主线程中被接收处理
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
Message msg = Message.obtain();
msg.what = 0x11;
handler.sendMessage(msg);
handler.sendEmptyMessage(0x11);
handler.sendMessageDelayed(msg, 1000);
2、Activity.runOnUiThread(Runnable)
runOnUiThread(new Runnable() {
@Override
public void run() {
//do something
}
});
追踪runOnUiThread这个方法,可以发现,方法内部也是使用Handler把Runnable送到主线程中执行。如果调用runOnUiiThread方法时不是处于主线程,则用handler发送Runnable,否则在主线程则直接执行Runnable。
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
3、View.post(Runnable),View.postDelay(Runnable, long)
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
跟踪post、postDelay方法,发现,当调用View.post方法时,View已经初始化完毕,会使用Handler发送执行Runnable,否则把Runnable发送到HandlerActionQueue中。HandlerActionQueue这个类保存着将要被Handler处理的Runnable,待View初始化完毕,会从HandlerActionQueue取出Runnable并交由Handler发送执行。
#View.java
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
...
// Transfer all pending runnables.
//view初始化完,开始执行Runnable
if (mRunQueue != null) {
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
...
}
#HandlerActionQueue.java
public void executeActions(Handler handler) {
synchronized (this) {
final HandlerAction[] actions = mActions;
for (int i = 0, count = mCount; i < count; i++) {
final HandlerAction handlerAction = actions[i];
handler.postDelayed(handlerAction.action, handlerAction.delay);
}
mActions = null;
mCount = 0;
}
}
总结,更新UI的几种方式最终都是通过Handler来实现。