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;
}
}
};
属于最原始的写法,但是其弊端是没有回收利用机制,如果一个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();
这种方式是最常用的,因为此方式创建的消息可以被回收利用,而且也很方便),也是通过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的方法,都是只能此时创建此时用。