handler缺点:如果要运送两种类型的数据(比如一个Bitmap,一个Object)就不能运送,但可以用Bunder来传输
* 使用handler的步骤:
* 1、创建一个handler
* 2、在需要用到数据传输的地方通过handler得到message对象,通过message携带要传输的数据
* 3、直接通过handler发送消息到主线程
* 4、在主线中通过重写handlerMessage,接收传输过来的数据
如果在onCreate启动的子线程做的操作不耗时,这个时候操作控件,错误是存在的,只是没有检测出来,因为这个时候控件还没来得及绘制
子线程向主线程传送消息
程序步骤:
1、发送一个空消息(不用构造message对象,而是直接给一个消息标记)
handler.sendEmptyMessage(1);
2、发送一个带message的信息
//1.通过Handler得到一个信息
Message message = handler.obtainMessage();
// Message message2 = Message.obtain();
//2.通过这个信息,携带数据
message.obj = "" ; //用来传输复杂数据
message.arg1 = 100; //用来传输简单整数类型
message.arg2 = 200; //用来传输简单整数类型
message.what = 300; //一般用来给message打标记的,因为一般可以传多个message
//3.利用handler发送消息,从子线程发送到主线程
handler.sendMessage(message);
//发送延迟消息
//handler.sendMessageDelayed(message, 3000); //隔3秒后再发送消息
//handler.sendEmptyMessageDelayed(5, 3000);
主线程向子线程传送消息
步骤与上面类似。
在接收数据的地方new Handler(){} 并重写方法
在发送数据的地方sendMessage()
不一样的地方:
在接收数据的地方,要写Looper.prepare(); //相当于初始化looper对象
Looper.loop(); //循环
总结:如果在主线程中接收消息,就不用写Looper,因为主线程中自带有一个Looper对象,并且也在循环工作;
但在子线程中没有looper对象,所以必须我们自己去创建,并且让它循环。所以,在子线程中接收数据之
前要先调用Looper.prepare()方法,再调用Looper.loop()方法
//子线程中只要有了looper对象,就可以写吐司。主线程中自带有looper对象,所以可以直接写吐司。
//如果把吐司写到Looper.prepare();之前就会报错。
图片的循环播放 开启一个子线程,做一个死循环
注意:在子线程中延迟发送要用Thread.sleep()方法,不能用handler.sendMessageDelayed(message, 2000);
因为子线程一旦启动了,就会一直进行,所以效果就是只有第一次会延迟发送消息,后面的就不会了,就会
一直发送。而在主线程中就可以使用handler.sendMessageDelayed(message, 2000);来延迟发送