转载:http://www.apkbus.com/blog-815579-61293.html
只是给自己做一下笔记而已。
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;
取Message对象的最好方法是调用Message.obtain()或者Handler.obtainMessage(), 这样是从一个可回收对象池中获取Message对象。
(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对象时,重写此方法;
@Override
protected 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