在Android开发中,更新UI有以下四种常用方式。
方式一:
方式二:
Handler类的post()方法。
方式三:
View类的post()方法。
方式四:
Activity类的runOnUiThread()方法。
先来看一下方式一sendEmptyMessage()的实现。
可以看到,最终会执行到下面两行代码。
(2).将msg添加到消息队列mQueue。
在构造方法中,Looper.myLooper()从当前线程中获取绑定的Looper对象,赋值给成员变量mLooper,再从mLooper对象中获取到mQueue对象。
Looper类的mQueue对象是何时创建的呢?
看一下Looper类的构造方法。
接下来,我们将要关心的就是,Looper对象是在哪里创建的。
这时需要进入到ActivityThread类。
(注:ActivityThread.java文件的路径:\platform_frameworks_base\core\java\android\app\ActivityThread.java)
ActivityThread管理应用程序的主线程的执行。 主线程之所以可以使用Handler进行通信,是因为主线程中已经创建了Looper。如果子线程需要使用Handler通信,需要自己去创建Looper。
来看一下ActivityThread类的main()方法。
在main()方法中,调用了Looper.prepareMainLooper()和Looper.loop()两个方法。
(1).Looper.prepareMainLooper()方法
在prepareMainLooper()方法中调用prepare()新建了一个looper对象,并通过threadLocal.set()方法与当前线程进行了绑定。
这里再回到Handler类的构造方法,在构造方法中是通过mLooper = Looper.myLooper()获取Looper对象。
进入Looper.myLooper()方法:
在Looper.loop()方法中,循环从MessageQueue中获取Message对象,调用msg.target.dispatchMessage(msg)进行处理,即将msg交给发送它的Handler对象的dispatchMessage()方法。
兜了一大圈,我们又再次回到Handler类。
在Handler类的dispatchMessage()方法中,我们终于看到了熟悉的handleMessage(Message msg)方法。
到这里,我们已经明白了,通过Handler类的的sendMessage(msg)发送的消息,最终是如何执行到handleMessage(Message msg)方法中。
方式一:
Handler类的sendEmptyMessage()或sendMessage()方法。
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_REFRESH) {
mTextView.setText("blog.csdn.net/ruancoder");
}
}
};
private void refresh1() {
mHandler.sendEmptyMessage(MSG_REFRESH);
}
方式二:
Handler类的post()方法。
private void refresh2() {
mHandler.post(new Runnable() {
@Override
public void run() {
mTextView.setText("blog.csdn.net/ruancoder");
}
});
}
方式三:
View类的post()方法。
private void refresh3() {
mTextView.post(new Runnable() {
@Override
public void run() {
mTextView.setText("blog.csdn.net/ruancoder");
}
});
}
方式四:
Activity类的runOnUiThread()方法。
private void refresh4() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText("blog.csdn.net/ruancoder");
}
});
}
先来看一下方式一sendEmptyMessage()的实现。
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
再来看一下方式二Handler类的post()方法。
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
我们会发现,这两种方式内部都是调用了sendEmptyMessageDelayed()方法,即都是采用Handler类发送消息的方式。
接着看方式三View类的post()方法。
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
其内部调用的是Handler类的post()方法,即上述方式二。
再看Activity类的runOnUiThread()方法。
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
其内部调用的是也是Handler类的post()方法,即上述方式二。
可以看到,上述四种方式都会执行到sendEmptyMessageDelayed()方法。
也就是说,即使采用后三种方式,最终都会执行第一种方式的实现。即Handler发送消息,然后在Handler类的handlerMessage()中接收消息。
我们接着sendEmptyMessageDelayed()方法继续往下走。
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
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);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
可以看到,最终会执行到下面两行代码。
msg.target = this;
mQueue.enqueueMessage(msg, uptimeMillis);
(1).将当前发送msg的Handler对象,赋值给msg的target属性。(2).将msg添加到消息队列mQueue。
此时,在Handler类中,我们已经无法进行接下来的执行流程了。那么最终消息是如何到达Handler类的handleMessage(Message msg)方法的呢?
下面我们来进行分析。
在Handler机制中涉及到四个重要的类,Handler、Looper、MessageQueue、Message。
Handler类中定义了成员变量mQueue和mLooper,分别是MessageQueue和Looper类型对象。
Handler类的成员变量:
public class Handler {
// other code
final MessageQueue mQueue;
final Looper mLooper;
// other code
}
Handler类的构造方法:
public Handler(Callback callback, boolean async) {
// other code
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
// other code
}
在构造方法中,Looper.myLooper()从当前线程中获取绑定的Looper对象,赋值给成员变量mLooper,再从mLooper对象中获取到mQueue对象。
Looper类的mQueue对象是何时创建的呢?
看一下Looper类的构造方法。
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
当Looper对象创建时,就会创建一个MessageQueue类型对象mQueue。
接下来,我们将要关心的就是,Looper对象是在哪里创建的。
这时需要进入到ActivityThread类。
(注:ActivityThread.java文件的路径:\platform_frameworks_base\core\java\android\app\ActivityThread.java)
ActivityThread管理应用程序的主线程的执行。 主线程之所以可以使用Handler进行通信,是因为主线程中已经创建了Looper。如果子线程需要使用Handler通信,需要自己去创建Looper。
来看一下ActivityThread类的main()方法。
public static void main(String[] args) {
// other code
Looper.prepareMainLooper();
Looper.loop();
// other code
}
在main()方法中,调用了Looper.prepareMainLooper()和Looper.loop()两个方法。
(1).Looper.prepareMainLooper()方法
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
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));
}
在prepareMainLooper()方法中调用prepare()新建了一个looper对象,并通过threadLocal.set()方法与当前线程进行了绑定。
这里再回到Handler类的构造方法,在构造方法中是通过mLooper = Looper.myLooper()获取Looper对象。
进入Looper.myLooper()方法:
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
该方法返回的就是上面sThreadLocal通过set()添加的Looper对象。
(2).Looper.loop()方法
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
// other code
for (;;) {
Message msg = queue.next();
msg.target.dispatchMessage(msg);
// other code
}
// other code
}
在Looper.loop()方法中,循环从MessageQueue中获取Message对象,调用msg.target.dispatchMessage(msg)进行处理,即将msg交给发送它的Handler对象的dispatchMessage()方法。
兜了一大圈,我们又再次回到Handler类。
在Handler类的dispatchMessage()方法中,我们终于看到了熟悉的handleMessage(Message msg)方法。
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
到这里,我们已经明白了,通过Handler类的的sendMessage(msg)发送的消息,最终是如何执行到handleMessage(Message msg)方法中。