1、Looper/Handler/Message
Handler | 通过sendMessage()发送Message到MessageQueue队列 |
---|---|
Looper | 通过loop(),不断提取出达到触发条件的Message,并将Message交给target来处理 |
Message | 经过dispatchMessage()后,交回给发送Message的Handler通过handlerMessage()来进行相应地处理 |
2、Looper.prepare()
子线程中需要先调用Looper.prepare(),才能再创建Handler对象
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Handler subHandler = new Handler();
}
}).start();
主线程中无需手动调用Looper.prepare(),可直接创建Handler对象
(因为系统在ActivityThread中的main()方法已经自动调用了Looper.prepare()方法)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thread);
Handler mainHandler = new Handler();
}
注:1)每个线程中最多只会有一个Looper对象
2)主线程中会始终存在一个Looper对象,从而不需要再手动去调用Looper.prepare()方法
3、Message的入队和出队
1)发送消息/入队
Handler中提供了很多个发送消息的方法,其中除了sendMessageAtFrontOfQueue()方法之外,其它的发送消息方法最终都会辗转调用到sendMessageAtTime()方法中
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
msg | 发送的Message对象 |
---|---|
uptimeMillis | 发送Message的时间 |
注:入队就是将所有的消息按时间uptimeMillis来进行排序,根据时间的顺序调用msg.next,从而为每一个消息指定它的下一个消息是什么。
若通过sendMessageAtFrontOfQueue()方法来发送消息,它也会调用enqueueMessage()来让消息入队,只不过时间为0,这时会把mMessages赋值为新入队的这条消息,然后将这条消息的next指定为刚才的mMessages,这样也就完成了添加消息到队列头部的操作。
2)出队/接受消息
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
return;
}
if (me.mLogging!= null) me.mLogging.println(">>>>> Dispatching to " + msg.target + " "+ msg.callback + ": " + msg.what);
msg.target.dispatchMessage(msg);
if (me.mLogging!= null) me.mLogging.println("<<<<< Finished to " + msg.target + " "+ msg.callback);
msg.recycle();
}
}
}
next()方法就是消息队列的出队方法,如果当前MessageQueue中存在mMessages(即待处理消息),就将这个消息出队,然后让下一条消息成为mMessages,否则就进入一个阻塞状态,一直等到有新的消息入队。
每当有一个消息出队,就将它传递到msg.target的dispatchMessage()方法。
msg.target就是Handler,在上面的sendMessageAtTime()方法中可以看出。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
4、子线程中进行UI操作
1)Handler的sendMessage()
2)Handler的post()
3)View的post()
4)Activity的runOnUiThread()
Handler的post() — dispatchMessage()中msg.callback != null
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
private final Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
View的post() — 调用Handler的post()
public boolean post(Runnable action) {
Handler handler;
if (mAttachInfo != null) {
handler = mAttachInfo.mHandler;
} else {
ViewRoot.getRunQueue().post(action);
return true;
}
return handler.post(action);
}
Activity的runOnUiThread() — 调用Handler的post()
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}