1、Handler(消息处理者)
<1>使用handeler的步骤:
(1)创建一个Handler;
private Handler handler = new Handler(){//用来接收和处理从子线程发送回来的信息,在主线程中接收public void handleMessage(Message msg) { String content = (String) msg.obj; int arg1 = msg.arg1; int arg2 = msg.arg2; int what = msg.what; textView.setText(content+arg1 +arg2 +what); };};
(2)在需要用到数据传输的地方通过handler得到message对象,通过message携带要传输的数据;
//1.通过handler得到一个信息Message message = handler.obtainMessage();//2.通过这个信息,携带数据message.obj = content;message.arg1 = 100;message.arg2 = 200;message.what = 300;
(3)直接通过handler发送消息,到主线程;
//3.利用了handler发送消息,从子线程发送到了主线程 handler.sendMessage(message);
(4)通过重写handleMessage()方法,接收传输过来的数据。
//用来接收和处理从子线程发送回来的信息,在主线程中接收public void handleMessage(Message msg) { String content = (String) msg.obj; int arg1 = msg.arg1; int arg2 = msg.arg2; int what = msg.what; textView.setText(content+arg1 +arg2 +what);};
<2>handleMessage():在主线程中,构造Handler对象时,重写此方法;
@Overrideprotected void onCreate(Bundle savedInstanceState) { ......}
<3>sendEmptyMessage():用在子线程中,发送空消息;
//1.发送一个空消息(不用构造message对象,而是直接给一个消息标记)handler.sendEmptyMessage(1);
<4>sendMessage():用在工作线程中,立即发送消息;
handler.sendMessage(message);//发送延迟消息 3000:延迟的时间(单位是毫秒)//handler.sendMessageDelayed(message, 3000);//发送延迟空消息//handler.sendEmptyMessageDelayed(5, 3000);
2、Message(消息)
<1>使用Message需要注意4点:
(1)Message虽然也可以通过new来获取,但是通常使用Message.obtain()或Handler.obtainMessage()方法来从消息池中获得空消息对象,以节省资源;
//2.发送一个带message的信息Message message = handler.obtainMessage();//获取到一个信息对象Message message2 = Message.obtain();
(2)如果一个Message只需要携带简单的int型数据,应优先使用arg1和arg2属性来传递数据,这样比其他方式节省内存;
message.arg1 = 2; //arg1和arg2都是用来传输整形message.arg2 = 3;
(3)尽可能使用Message.what来标识信息,以便用不同的方式处理Message。
message.what = 4; //也是用来传输整数类型,但是一般用来传输message标记
(4)如果需要从工作线程返回很多数据信息,可以借助Bundle对象将这些数据集中到一起,然后存放到obj属性中,再返回到主线程。
<2>arg1:用来存放整型数据
<3>arg2:用来存放整形数据
<4>obj:用来存放Object数据
<5>what:用于指定用户自定义的消息代码,便于主线程接收后,根据消息代码不同而执行不同的操作
3、Thread(将消息发送给主线程)
4、Handler运行原理
<1>Handler、Looper、Message、MessageQueue之间的关系:
Handler,Looper和MessageQueue的三角关系
<2>Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue;而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue;
在一个线程中,只能有一个Looper和MessageQueue,但是可以有多个Handler,而且这些Handler可以共享一个Looper和MessageQueue;
<3>Message被存放在 MessageQueue中,一个 MessageQueue中可以包含多个Message对象。
【备注:】
(1)Looper对象用来为一个线程开启一个消息循环,从而操作MessageQueue;
(2)默认情况下,Android创建的线程没有开启消息循环,但是主线程例外。
(3)系统自动为主线程创建Looper对象,开启消息循环;
(4)所以主线程中使用new来创建Handler对象。而子线程中不能直接new来创建Handler对象就会异常。
(5)利用handler把数据从主线程中发送到子线程:
在主线程中,自带一个有loop对象,并且这个loop对象在循环工作;
但是在子线程中接收数据之前先调用Looper.prepare(),再调用Looper.loop()方法。
(6)子线程中创建Handler对象,步骤如下:
Looper.prepare();
Handler handler = new Handler() {
//handlemessage(){}
}
Looper.loop();
<4>Looper:消息泵,不断地从MessageQueue中抽取Message执行。一个MessageQueue需要一个Looper
<5>Hanlder:消息处理者
(1)在新启动的工作线程中发送消息
(2)在主线程中获取、并处理消息
<6>MeessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行
<7>Message:消息,包含线程处理的数据和消息参数
<8>Thread:通过主线程的handler对象发送消息给主线程,并更新UI