Android消息傳遞之Handler消息機制


前言:

      無論是現在所做的項目還是以前的項目中,都會遇見線程之間通信、組件之間通信,目前統一采用EventBus來做處理,在總結學習EventBus之前,覺得還是需要學習總結一下最初的實現方式,也算是不忘初心吧,這也是今天來學習總結Handler消息機制的一個原因。

  消息傳遞相關文章地址:

Handler機制產生背景

      一個Android應用程序被創建的時候都會創建一個UI主線程,但是有時我們會有一些比較耗時的操作,為了防止阻塞UI主線程,我們會將耗時的操作放到子線程中進行處理,處理完之后操作UI,但是Android不允許子線程操作UI,違背了Android單線程模型的原則(即 Android UI操作並不是線程安全的並且這些操作必須在UI線程中執行),所以Android通過Handler消息機制來實現線程之間的通訊。

Handler機制主要角色

    Message:消息,其中包含了消息ID,消息處理對象以及處理的數據等,由MessageQueue統一列隊,終由Handler處理。 

    Handler:處理者,負責Message的發送及處理。使用Handler時,需要實現handleMessage(Message msg)方法來對特定的Message進行處理,例如更新UI等。 

    MessageQueue:消息隊列,用來存放Handler發送過來的消息,並按照FIFO規則執行。當然,存放Message並非實際意義的保存,而是將Message以鏈表的方式串聯起來的,等待Looper的抽取。 

    Looper:消息泵,不斷地從MessageQueue中抽取Message執行。因此,一個MessageQueue需要一個Looper。 

    Thread:線程,負責調度整個消息循環,即消息循環的執行場所。

Handler機制主要運用

    1.)發送消息,在不同的線程間發送消息,使用的方法為sendXXX();
sendEmptyMessage(int);//發送一個空的消息
sendMessage(Message);//發送消息,消息中可以攜帶參數
sendMessageAtTime(Message, long);//未來某一時間點發送消息
sendMessageDelayed(Message, long);//延時Nms發送消息

 舉例:

 主線程定義Handler

  Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    //完成主界面更新,拿到數據
                    String data = (String) msg.obj;
                    textView.setText(data);
                    break;
                default:
                    break;
            }
        }
    };

子線程發消息,通知Handler完成UI更新

    private void getDataFromNet() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                //耗時操作,完成之后發送消息給Handler,完成UI更新;
                mHandler.sendEmptyMessage(0);

                //需要數據傳遞,用下面方法;
                Message msg = new Message();
                msg.obj = "網絡數據";//可以是基本類型,可以是對象,可以是List、map等;
                mHandler.sendMessage(msg);
            }

        }).start();
    }
2.)計划任務,在未來執行某任務,使用的方法為postXXX();
post(Runnable);//提交計划任務馬上執行
postAtTime(Runnable, long);//提交計划任務在未來的時間點執行
postDelayed(Runnable, long);//提交計划任務延時Nms執行

示例:

主線程定義Handler

  private Handler mHandler=new Handler();

子線程提交任務更新UI

    private void getDataFromNet() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                //耗時操作,完成之后提交任務更新UI
                final String data = "網絡數據";
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(data);
                    }
                });
            }
        }).start();
    }

Handler機制擴展

    為了更加方便的使用Handler消息機制,Android也提供了幾種擴展方式,內部實現都是基於Handler消息機制

  1.) Activity.runOnUiThread(Runnable)
    private void getDataFromNet() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                //耗時操作,完成之后提交任務更新UI
                final String data = "網絡數據";
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(data);
                    }
                });
            }
        }).start();
    }
2 .)View.post(Runnable)
   private void getDataFromNet() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                //耗時操作,完成之后提交任務更新UI
                final String data = "網絡數據";
                textView.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(data);
                    }
                });
            }
        }).start();
    }

5.)使用AsyncTask代替Thread

    private void getDataFromNet() {
        MyTask task = new MyTask();
        task.execute();
    }

    private class MyTask extends AsyncTask {

        //后台線程執行時
        @Override
        protected Object doInBackground(Object... params) {
            ////耗時操作,
            String data = "網絡數據";
            return data;
        }

        //后台線程執行結束后的操作,其中參數result為doInBackground返回的結果
        @Override
        protected void onPostExecute(Object result) {
            super.onPostExecute(result);
            textView.setText((String) result);
        }
    }

小結:

    至此Handler消息簡單的總結到此結束,更多內部具體實現可以參考

   1.http://www.cnblogs.com/angeldevil/p/3340644.html

   2.http://blog.csdn.net/fei0724/article/details/8664462

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM