handle作用:是滿足線程與線程之間通信的
線程一旦被創建就會生成一個Looper對象,有且僅有一個
每個應用在運行的時候都會創建一個主線程(mainThread)。
主線程不能做耗時操作,子線程不能更新UI
Looper:一個線程可以產生一個Loop對象,由它來循環MessageQueue(消息隊列)
handler:通過Handler對象和Looper進行溝通,以便發送消息到MessageQueue或者接收Looper從MessageQueue中讀取的消息
MessageQueue:用來存放線程放入的消息
線程:UIThread通常就是mian thread,而Android啓動程序的時候就會替它建立一個MessageQueue。
private Handler handler = new Handler() {
//接收子線程中發送過來的消息
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
//通過obj的方式來獲取方法
text_tv.setText((String) msg.obj);
break;
case 2:
//通過bundle的方法來獲取數據
text_tv.setText((String) msg.getData().getString("message"));
break;
case 3:
//通過bundle的方法來獲取數據
text_tv.setText((String) msg.getData().getString("data"));
break;
}
}
};
第一種是通過new Message()的方法來新建消息(屬於最原始的寫法,但是其弊端是沒有回收利用機制,如果一個APP中新建了很多消息而沒有回收,那麼會帶來系統可卡頓,不利於系統的優化),通過what添加標識,通過obj添加內容存放數據(當然我們也可以通過bundle來存放數據,都是可以的)。
new Thread() {
@Override
public void run() {
//使用handler進行獻策之間的消息通信
Message message = new Message();
//給message添加標識
message.what = 1;
//給message添加內容
message.obj = "今天天氣不錯";
//向消息隊列中發送消息
handler.sendMessage(message);
}
}.start();
第二種是通過Message.obtain的方法(這種方式是最常用的,因爲此方式創建的消息可以被回收利用,而且也很方便),也是通過what來添加標識,通過bundle來存放數據(也是可以用obj來存放,都一樣)。
new Thread() {
@Override
public void run() {
//通過Message的obtain來創建消息,那麼此消息可以被回收利用
Message obtain = Message.obtain();
obtain.what = 3;
bundle.putString("data", "下雪了今天。");
obtain.setData(bundle);
handler.sendMessage(obtain);
}
}.start();
用bundle存放數據和用obj存放數據的利弊:
bundle是一個鍵值對,可以定義成一個全局變量,進而多次使用,每次傳不同的鍵名即可。而且bundle所傳的的數據類型明確指明的有很多,傳不同類型時很方便,和intent有點類似。
obj是一個萬能的類型,可以傳任何類型,但是拿的時候要強轉,並且對於一些特殊類型不如bundle使用方便。當然,對於基本數據類型,還是obj來的方便一點。
new Thread(){
@Override
public void run() {
Message msg = new Message();
//使用bundle來存放數據,可以放集合
bundle.putString("message", "太陽出來了");
msg.setData(bundle);
msg.what = 2;
handler.sendMessage(msg);
}
}.start();
注:消息時不能抽成全局變量來使用,無論是使用new Message的方法還是通過Message.obtain的方法,都是隻能此時創建此時用。