1. 程式人生 > >Android 中幾種更新UI介面的方法

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總結,自勉,不足之處還望指出