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();
}
}