android handler、looper、message、messageQueue、
一:handler,looper,message,messagequeue,thread
handler: 消息处理着,负责Message消息的发送(handler.sendMessage(....))以及处理消息,对于handler处理消息则需要实现handlerMessage(Message msg)该方法,通过该方法处理特定的消息,例如ui的更细
looper:消息泵,用来从messageQueue中抽取消息,所以一个looper对应一个messageQueue;
message:消息,message中含有该消息的ID以及消息处理对象或者处理的数据,通过messageQueue消息队列同一处理。
messageQueue,消息队列,messageQueue中保存 通过handler发送来的消息,当然该保存不是真正意义上保存,而是以链式结构将消息链接起来。等待looper的抽取
thread:线程,负的调度整个消息循环,即消息循环的场所执行
二:handler、looper、messageQueue之间的关系
looper与messageQueue是一一对应的关系,及创建一个looper的同时创建一个messageQueue,handler与它们只是简单的聚合关系,handler中会引用当前线程中的looper与messageQueue,从这里可以看出对个handler 能够同时处理一个looper与messageQueue,前提是这些handler都在同一个线程中
三:简单实例:
消息的生成:
Message msg=Handler.obtiainMessage();
msg.what=what;
msg.sendToTarget();
消息发送:
MessageQueue queue=looper.myQueue();
//通过该对象找到与之对应的消息队列messageQueue
if(queue!=null){
msg.target=this
sent = queue.enqueueMessage(msg, uptimeMillis);
}
注:在handler的sendMessageAtTme(Message msg,long time)中可以看出handler 找到自己线程中的MessageQueue中的message 然后将message的target设置为handler自己,目的是message能够找到正确的handler。
三:抽取
//得到handler所在线程中的looper对象;
Looper looper=handler1.getLooper();
//通过该对象找到与之对应的消息队列messageQueue
MessageQueue queue=looper.myQueue();
while (true) {
Message msg = queue.next(); //不断的从消息队列中获取消息
if (msg != null) {
if (msg.target == null) {
return;
}
msg.target.dispatchMessage(msg);
msg.recycle();
}
}
从这里我们可以看出 不断的从消息队列中获取消息,然后通过message的target中携带的信息去,寻找正确的handler 用来处理该消息
四:处理:
handler = new Handler(){
复写handlerMessage(Message msg);
}
至此,我们看到,一个Message经由Handler的发送,MessageQueue的入队,Looper的抽取,又再一次地回到Handler的怀抱。而绕的这一圈,也正好帮助我们将同步操作变成了异步操作。
小实例:跟新UI
首先在主线程中如果我们使用handler不创建looper对象,则系统会默认使用主线程中已经创建好的looper对象,然而在非ui线程中我们使用handler而不传入looper对象,则这个handler不能接受消息。
通常的做法是:
Thread thread = new Thread() {
@Override
public void run() {
//创建handler之前我们需要首先准备一个looper
Looper.prepare();
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
super.run();
}
};
//将该looper启动(跑起来)这样就能够从messageQueue中抽取message 这样handler才能正常运行
Looper.loop();
thread.start();
}
注:handler 处理消息总是在创建该handler的线程中运行,而我们的消息处理中,不乏更新UI的操作,不正确的线程直接更新UI将引发异常,因此我们需要实时注意handler所在的线程。
小结:
- handler 的处理运行是在创建该handler的线程中运行
- 一个looper对应一个messageQueue
- 一个线程对应一个looper
- 一个looper可以对应多个handler(这些handler在同一个线程中)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。