Android中更新UI的几种方式:
1. Activity 的 runOnUiThread()
2. Handler 的 post()
3. Handler 的 sendMessage()
4. View 的 post()
代码实现:
1.使用Handler的post():
public void handlerChangeUI(){
handler.post(new Runnable(){
@Override
public void run() {
textView.setText("OK");
}
});
}
2. 使用Handler的sendMessage():
public void handlerChangeUI2(){
handler.sendEmptyMessage(1);
}
3. 使用Activity的runOnUiThread():
public void activityUpdateUI(){
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("Changed by Activity");
}
});
}
4. 使用View的 post():
public void viewUpdateUI(){
textView.post(new Runnable() {
@Override
public void run() {
textView.setText("UI was updated by view.post");
}
});
}
最后在 onCreate()内部创建一个线程,依次调用如上四种方法,观察结果。
new Thread(){
@Override
public void run() {
try {
Thread.sleep(1000);
// handlerChangeUI();
// handlerChangeUI2()
// activityUpdateUI()
viewUpdateUI();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
查看源码可发现,handler的post()内部调用了 sendMessageDelayed()方法,和我们普通发送Message是一样的,只不过它还要先调用getPostMessage()方法: public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r),0); } private static Message getPostMessage(Runnable r){ Message m = Message.obtain(); m.callback = r; ruturn m; } 原来Callback就是一个Runnable对象。 总之,handler使用post()去发送一个Runnable,其实它内部也是封装了Message去发送的,本质上和直接发送Message没有区别。 那么Activity的runOnUiThread()又是如何更新UI的呢? public final void runOnUiThread(Runnable action){ if(Thread.currentThraed()!= mUiThread){ mHandler.post(action); // mHandler是Activity自己的Handler对象 }else{ action.run(); } } 首先,判断当前线程是不是UI线程,不是的话,则调用Activity自己的Handler对象,通过该对象发送一个Runnable;如果是,则调用UI线程的run()方法。 所以,Activity的runOnUiThread()内部也是使用了Handler机制去更新UI。
最后,看一下View的post()方法。 public boolean post(Runnable action){ final AttachInfo attachInfo = mAttachInfo; if(attachInfo != null){ return attachInfo.mHandler.poat(action); } ViewRootImpl.getRunQueue().post(action); return true; } 首先判断 attachInfo 是否为空。如果不为空,则通过 attachInfo 的Handler对象去post一个Runnable对象。如果为空,则调用ViewRootImpl的getRunQueue去拿到一个Handler去post一个Runnable对象。其中,ViewRootImpl 和更新UI的机制有着密切相关的联系。 综上,更新UI的四种方法,本质上都是通过Handler机制去更新UI的。