Android面試常客-Handler上(handler的使用)

handler是什麼?

handler是android給我們提供的用來更新UI的一套機制,也是一套消息處理機制,我們可以用來發送消息,也可以通過它來處理消息,在android中,anctivty的生命週期就是有handler實現。

爲什麼要用handler?可以不用嗎?

是不可以的,Android在設計的時候,就封裝了一套消息創建,傳遞,處理機制,如果不遵循這樣的機制的話就沒有辦法更新UI信息,就會拋出異常信息。

handler的用法

handler用法一

handler在android developers中的說明

那麼在官方給出的handler說明中主要說明了:我們創建一個handler的時候,會跟一個默認的線程綁定,這個線程中就有一個Message queue,Message queue就是一個消息隊列。

handler的作用:

  • 定時發送一個消息或者Runnable
  • 在一個線程中處理一個動作

在非UI線程跟新UI會出現什麼異常?

創建一個android項目
MainActivity.java

public class MainActivity extends AppCompatActivity {

private TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView= (TextView) findViewById(R.id.textView);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    textView.setText("I am Bree ");
                }
            }).start();
        }
    }

activity_main.xml

      <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

運行項目會出現以下異常

    03-15 14:29:46.953 5774-5800/bree.com.handlertest E/AndroidRuntime: FATAL EXCEPTION: Thread-350
                                                                Process: bree.com.handlertest, PID: 5774
                                                                android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6118)
                                                                    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:837)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
                                                                    at android.view.View.requestLayout(View.java:16648)
                                                                    at android.widget.TextView.checkForRelayout(TextView.java:6610)
                                                                    at android.widget.TextView.setText(TextView.java:3822)
                                                                    at android.widget.TextView.setText(TextView.java:3680)
                                                                    at android.widget.TextView.setText(TextView.java:3655)
                                                                    at bree.com.handlertest.MainActivity$1.run(MainActivity.java:24)
                                                                    at java.lang.Thread.run(Thread.java:841)

異常信息爲不可以在子線程中更新UI,在android開發中是不允許的。

handler.post(Runnable runnable)

使用這個方法進行更新UI,修改MainActivity中的代碼,如下:

        public class MainActivity extends AppCompatActivity {

        private TextView textView;
        private Handler handler=new Handler();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView= (TextView) findViewById(R.id.textView);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText("I am Bree ");
                        }
                    });
                }
            }).start();
        }
    }

在子線程中使用handler就可以修改TextView中顯示的內容。

handler.postDelayed(Runnable runnable,long time)

這個方法的意思是在time毫秒後執行Runnable中定義的動作,再次不做代碼粘貼了,大家可自行測試。

handler用法二

MainAvtivity.java

    public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private Handler handler=new Handler(new Handler.Callback() {
        /**
         * 此方法如果返回ture則攔截發過來的消息
         * @param message
         * @return
         */
        @Override
        public boolean handleMessage(Message message) {
            return false;
        }
    }){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //根據msg處理消息
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView= (TextView) findViewById(R.id.textView);
        new Thread(new Runnable() {
            @Override
            public void run() {

                //1發送一個空消息
                handler.sendEmptyMessage(1);

                //2.發送一個Message
                //handler.obtainMessage();由系統之取出Message的對象,如果沒有則自動新建
                //也可以Message message=new Message();  當然啦既然系統都提供了,咱麼就不要新建啦
                Message message=handler.obtainMessage();
                message.arg1=1;
                message.what=10;
                //message.obj=發送一個對象
                handler.sendMessage(message);
            }
        }).start();
    }
}
發佈了32 篇原創文章 · 獲贊 0 · 訪問量 9977
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章