天天看點

Handler消息機制之基礎代碼篇

在主線程中直接寫耗時操作的話很容易引起ANR異常,是以我們都把耗時操作寫在子線程中去完成,但執行完之後,想要更新頁面,又不允許在子線程中去更改頁面 --  異步任務 或加載器解決了此問題。除了以上兩種解決方式外,使用Thread +Handler也可實作上述效果。
           

“Handler的作用:注意是在android.os包下的類

(1)、發送并處理消息

(2)、可以排隊執行一系列的動作

此類介紹Handler的最最最基本使用

一. 發送空消息

static final int LOADING_START= ;
    static final int LOADING_FINISH=;

    Button  textView;

       /*
        *  建立Handler對象,
        * */
    Handler handler = new Handler(){

           //此處接收所有有目前handler對象通過send方法發出的消息
           //參數代表接收到的消息對象
        @Override
        public void handleMessage(Message msg) {
         //通過msg對象的what屬性取出目前接收到的消息的辨別
            if (msg.what == LOADING_FINISH) {

                textView.setText("我要當大牛");
            }
            super.handleMessage(msg);
        }
    };
           
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (Button) findViewById(R.id.textview);

    } 
           
//模拟按鈕  進行耗時操作
    public  void  click(View v) {

        new Thread(){
            @Override
            public void run() {

                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //更新頁面操作
                /*
                 * 如果直接在子線程執行更改UI的操作的話
                 * 會抛出CalledFromWrongThreadException
                 * 引起程式的崩潰
                 * 原因:規定子線程不允許操作UI頁面
                 *
                 * 注意:Toast,對話框這種彈出視窗的show方法也算是UI操作
                 * */
//              textView.setText("zss");
                //  Toast.makeText(MainActivity.this,"哈哈先生",Toast.LENGTH_SHORT);
                /*

                 * 不讓在子線程中寫,那麼我就想辦法把我要幹的事情傳出去,在某一個位置
                 * 接收到我在子線程中傳出的事情,并執行   通過Handler發送消息
                * */

                //發送一個空消息
                handler.sendEmptyMessage(LOADING_FINISH);
            }
        }.start();
    }
           

完整代碼已貼出,附有詳細注釋,上述代碼隻是發送了一個簡單的空消息。

補充知識點:對于上述發送的消息,結構為 耗時+發送的結構。現在我們改為 發送 + 耗時 +發送 代碼如下:

隻需在如下方法中添加這幾行代碼即可

public void handleMessage(Message msg) {
         //通過msg對象的what屬性取出目前接收到的消息的辨別
            if (msg.what == LOADING_FINISH) {

                textView.setText("我要當大牛");
            }else if(msg.what == LOADING_START){

                 textView.setText("等待時間");
            }
            super.handleMessage(msg);
        }
           
new Thread(){
            @Override
            public void run() {

                handler.sendEmptyMessage(LOADING_START);

                try {
                    Thread.sl
           

剩餘代碼都是一樣的,就不完整貼出了。

二. 發送非空消息

** //通過Handler發送非空消息

/*

* 當想要發送非空消息的時候,

* 1.封裝要發送的消息對象

* 在初始化Message對象的時候,推薦使用以下的初始化方式

* 原因:下面的方式比new 的方式效率高,節省記憶體“

* /*

//模拟按鈕  進行耗時操作
    public  void  click(View v) {

        new Thread(){
            @Override
            public void run() {

                //handler.sendEmptyMessage(LOADING_START);
                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

               // Message msg = Message.obtain();      //第一種方式
                Message msg = handler.obtainMessage();  //第二種方式
                //向msg中存取資料
                msg.what = LOADING_FINISH;
                msg.arg1 = ;
                msg.arg2 = ;
                msg.obj = System.currentTimeMillis();

                //調用sendMessage()方法   把Message的對象傳進去
                handler.sendMessage(msg);

            }
        }.start();
    }
           
Handler handler = new Handler(){

           //此處接收所有有目前handler對象通過send方法發出的消息
           //參數代表接收到的消息對象
        @Override
        public void handleMessage(Message msg) {
         //通過msg對象的what屬性取出目前接收到的消息的辨別

            int a =msg.arg1;    //取值
            int b =msg.arg2;   //取值
            Long s = (Long) msg.obj;

            textView.setText(a+" " + b+" " +s);
            super.handleMessage(msg);
        }
    };
           
如果想要存儲多個資料的話:采用Bundle 如下:
           
//模拟按鈕  進行耗時操作
    public  void  click(View v) {

        new Thread(){
            @Override
            public void run() {

                //handler.sendEmptyMessage(LOADING_START);
                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

               // Message msg = Message.obtain();      //第一種方式
                Message msg = handler.obtainMessage();  //第二種方式
                //向msg中存取資料
                msg.what = LOADING_FINISH;

                Bundle  bundle = new Bundle();
                bundle.putString("data", "dfasdfa");
                bundle.putBoolean("boo", true);
                msg.setData(bundle);

                //調用sendMessage()方法   把Message的對象傳進去
                handler.sendMessage(msg);

            }
        }.start();
    }
           
Handler handler = new Handler(){

           //此處接收所有有目前handler對象通過send方法發出的消息
           //參數代表接收到的消息對象
        @Override
        public void handleMessage(Message msg) {
         //通過msg對象的what屬性取出目前接收到的消息的辨別

            if(msg.what == LOADING_FINISH) {

                Bundle data = msg.getData();
                textView.setText(data.getString("data")+" "+data.getBoolean("boo"));
                super.handleMessage(msg);
            }
        }
    };
           
好了,第一節的簡單的handler的用法,先寫到這哈。以上代碼如有不妥指出,還望指出謝謝。。  
           

繼續閱讀