Android 中幾種更新UI介面的方法
android 更新UI的幾種方法
根據之前的專案經驗,以及在網上看到的一些技術文章,將UI更新的幾種方法在此做個總結:(補充一點,不要混淆了Runnable和Thread,Runnable只是個單純的任務,只是啟動這個任務需要執行緒來驅動,而這個執行緒可以是主執行緒,也可以是子執行緒。認清這點非常重要)
1. 利用Android Handler機制和message訊息傳遞
我們知道 , Android Handler機制主要用作執行緒之間的通訊,為了易於理解,我們暫不考慮每個執行緒的Looper問題。UI更新一般是在主執行緒中完成的,而Handler就是定義在主執行緒中,然後通過在Handler構造方法中重寫HandlerMessage()方法,來處理有其他執行緒(子執行緒)傳遞過來的訊息,從而達到更新UI的目的。相應的,在其他執行緒(子執行緒)中,我們通過SendMessage(message)方法來傳遞訊息。
//主執行緒中
private Handler mHandler = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0: //更新未消費訂單的數量
int[] count = (int[]) msg.obj;
//顯示資料
tv_unconsumptionSum.setText(count [0] + "");
tv_consumptionSum.setText(count[1] + "");
break;
default:
break;
}
}
};
//...
//子執行緒程式碼
//未消費訂單 和已消費訂單重新整理 handler 機制
new Thread(){
public void run() {
//step1 獲取資料
MyUser myUser = MyUser.getCurrentUser(MainActivity.this ,MyUser.class);
int count[] = {0,0}; //未消費選單 和 已消費選單
if(myUser.getmUnconsumptionOrder() != null){
count[0] = myUser.getmUnconsumptionOrder().size();
}
if(myUser.getmConsumptionOrder() != null){
count[1] = myUser.getmConsumptionOrder().size();
}
Message message = new Message();
message.what = 0;
message.obj = count;
mHandler.sendMessage(message);
}
}.start();
2.利用Android Handler機制和post
這個比較容易理解,也是UI更新常用的方法。 在一個新建的執行緒中進行更新介面的操作,然後在主執行緒中利用mHandler.post(Runnable runnable)來達到更新介面的目的,其中mHandler是在主執行緒中定義的。
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//相關資料處理
//...
//通知listview重新整理資料
listViewRestarant.reflashComplete();
}
}, 1000);
通過查詢原始碼知道post方法和postDelay方法和message的關係
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
所以用主執行緒中的handler來post其實也就是在執行sendMessage方法,其中getPostMessage方法的原始碼如下:
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
而obtain()方法則如下:從訊息池中獲取Message
/**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.
*/
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
那麼訊息池中的訊息什麼時侯會增加,通過原始碼查詢到了recycleUnchecked()—>recycle(),是的,沒錯就是在這裡訊息被回收,這讓我分分鐘想到了JAVA的GC機制。跟蹤到這兒我就暫停了,下次再補充,但是由於該方法是public 型別的,而且Message類中沒有呼叫,所以推測這個方法和Looper或者Handler有關。
3.以上兩種方法都是利用Handler機制在主執行緒中更新介面。現在講一種子執行緒中更新介面的方法 —— 通過runOnUiThread()方法來實現
class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
//資料處理
//...
runOnUiThread(new new Runnable() {
public void run() {
//重新整理介面
list.add(dog);
adapter.notifyDataSetChanged();
}
}
})
}
以上就是相關的UI更新常用方法,第一次寫CSDN總結,自勉,不足之處還望指出