快速切換到主線程更新UI的幾種方法

方法一: view.post(Runnable action)

假如該方法是在子線程中ide

textView.post(new Runnable() {
        @Override
        public void run() {
            textView.setText("更新textView");
            //還能夠更新其餘的控件
            imageView.setBackgroundResource(R.drawable.update);
        }
    });

 

方法二: activity.runOnUiThread(Runnable action)

public void updateUI(final Context context) {
        ((MainActivity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //此時已在主線程中,能夠更新UI了
            }
        });
    }

若是沒有上下文(context),試試下面的方法: 
1.用view.getContext()能夠獲得上下文。 
2.跳過context直接用new Activity().runOnUiThread(Runnable action)來切換到主線程。oop

方法三: Handler機制

首先在主線程中定義Handler,Handler mainHandler = new Handler();(必需要在主線程中定義才能操做主線程,若是想在其餘地方定義聲明時要這樣寫Handler mainHandler = new Handler(Looper.getMainLooper()),來獲取主線程的 Looper 和 Queue )post

Handler mainHandler = new Handler(Looper.getMainLooper());
    mainHandler.post(new Runnable() {
        @Override
        public void run() {
            //已在主線程中,能夠更新UI
        }
    });

Handler還有下面的方法: 
1.postAtTime(Runnable r, long uptimeMillis); //在某一時刻發送消息 
2.postAtDelayed(Runnable r, long delayMillis); //延遲delayMillis毫秒再發送消息spa

(2): 假設在主線程中線程

Handler myHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case 0:
                    //更新UI等
                    break;
                case 1:
                     //更新UI等
                    break;
                default:
                    break;
            }
        }
    }

 

/**
      *獲取消息,儘可能用obtainMessage()方法,查看源碼發現,該方法節省內存。
      *不提倡用Messenger msg=new Messenger()這種方法,每次都去建立一個對象,確定不節省內存啦!
      *至於爲何該方法還存在,估計仍是有存在的必要吧。(留做之後深刻研究)
      */
    Message msg = myHandler.obtainMessage();
    msg.what = 0; //消息標識
    myHandler.sendMessage(msg); //發送消息

如上代碼,只是發送了個消息標識,並無傳其餘參數。 
若是想傳遞參數,能夠這樣:code

msg.what = 1;  //消息標識
      msg.arg1=2;   //存放整形數據,若是攜帶數據簡單,優先使用arg1和arg2,比Bundle更節省內存。
      msg.arg2=3;   //存放整形數據
      Bundle bundle=new Bundle();
      bundle.putString("dd","adfasd");
      bundle.putInt("love",5);
      msg.setData(bundle);
      msg.obj=bundle;   //用來存放Object類型的任意對象
      myHandler.sendMessage(msg); //發送消息

總結: msg.obj它的功能比較強大一下,至於它和利用Bundle傳遞數據,那個會效率高一些,更節省內存一些。我的認爲:從傳遞數據的複雜程度看,由簡單到複雜依次使用,arg1, setData(), obj。會比較好一些。對象

固然能夠用簡化方法sendEmptyMessage(int what)來減小沒必要要的代碼,這樣寫:內存

myHandler.sendEmptyMessage(0); //其實內部實現仍是和上面同樣
  •  

發送消息的其餘方法有:get

endEmptyMessageAtTime(int what, long uptimeMillis); //定時發送空消息
sendEmptyMessageDelayed(int what, long delayMillis); //延時發送空消息
sendMessageAtTime(Message msg, long uptimeMillis); //定時發送消息
sendMessageDelayed(Message msg, long delayMillis); //延時發送消息
sendMessageAtFrontOfQueue(Message msg); //最早處理消息(慎用)

方法四: 使用AsyncTask

相關文章
相關標籤/搜索