Android中提供了Handler和Looper来满足Looper来满足线程之间的通讯,Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换
1.Looper:一个线程可以产生一个Looper对象,由它来管理此线程里面的MessageQueue
2.Handler:可以构建Handler对象与Looper交互,以便push新消息到MessageQueue连;或者接受Looper从MessageQueue取出所传输的消息
3.MessageQueue:用来存放线程放入的消息
4.线程:主线程启动时会自动创建一个MessageQueue
Handler处理消息
每一个 Message都需要被指定的Handler处理,通过Handler处理Message去完成这些功能。Android消息机制中引入消息池。所有的消息都会存入这个消息池中,如果没有这个消息实例,将会创建一个消息实例放入到消息池中。消息池的好处是:消息不被使用时,不会被回收,而是存在于消息池中,再下一次调用时使用。也就提高了消息对象的重复使用,减少垃圾回收的次数
Handler发送消息
在主线程中初始化第一个Handler时会通过ThreadLocal创建一个Looper,该Looper与主线程--对应,使用ThreadLocal的目的是为了保证每一个线程只创建一个Looper,之后其他的Handler初始化的时候直接获取到第一个Handler创建的Looper.Looper初始化的时候回创建一个消息队列MessageQueue,他们之间的关系是主线程:消息循环:消息队列==1:1:1,
Handler消息处理
组线程通过Looper循环查询消息队列,当发现有消息存在时会将消息从消息队列中取出。手下分析消息,通过消息的参数判断该消息对应的Hnadler,然后将消息发到指定的Handler进行处理
Handler:
public class Handler {
private Looper looper;
public Handler(Looper looper){
this.looper=looper;
}
/**发送消息*/
public void sendMessage(Message msg){
//关联handler
msg.target=this;
//存储消息
looper.getMsgQ().put(msg);
}
/**空方法*/
public void handleMessage(Message msg){}
//让r中的run方法在handler关联的looper所在线程执行
public void post(Runnable r){
Message m = new Message();
m.callback = r;
sendMessage(m);
}
}
Looper:
/**借助此对象迭代消息队列*/
public class Looper {
private static MessageQueue msgQ;
public MessageQueue getMsgQ() {
return msgQ;
}
private static boolean isLooper=true;
/**迭代消息队列*/
public static void loop(){
while(isLooper){
//从消息队列取消息
Message msg=msgQ.take();
//交给handler处理消息
if(msg.callback==null){
msg.target.handleMessage(msg);
}else{
msg.callback.run();
}
//target为handler对象
}
}
private Looper(){
msgQ=new MessageQueue();
}
private static ThreadLocal<Looper>
threadLocal=new ThreadLocal<Looper>();
/**借助此方法构建Looper对象*/
public static void prepare(){
//获得当前线程绑定的looper对象
if(threadLocal.get()!=null){
throw new RuntimeException("Looper 在此线程已经存在!");
}
//创建一个Looper并绑定到当前线程
threadLocal.set(new Looper());
}
public static Looper myLooper(){
return threadLocal.get();
}
/**退出Looper*/
public void quit(){
//从当前线程移除looper(解除绑定)
threadLocal.remove();
//退出迭代
isLooper=false;
}
}
Message:
/**消息对象:此对象用于封装线程之间要传递的数据*/
public class Message {
/**用于存储数据*/
Object obj;
/**表是这个消息对象是要做什么*/
int what;
//......
/**关联的handler对象*/
Handler target;
/**任务对象*/
Runnable callback;
}
MesageQueue:
/**此消息队列用于存储多个消息对象*/
public class MessageQueue {
private BlockingQueue<Message> msgQ=
new ArrayBlockingQueue<>(5);
/**此方法用于存储消息*/
public void put(Message msg){
try{
msgQ.put(msg);
}catch(Exception e){e.printStackTrace();}
}
/**此方法用于取消息*/
public Message take(){
try{
return msgQ.take();
}catch(Exception e){e.printStackTrace();
return null;
}
}
}
MSMDemo:
/**主线程给主线程发消息*/
public class MSMDemo {
public static void main(String[] args) {
Looper.prepare();
Handler h=new Handler(Looper.myLooper());
h.post(new Runnable() {//底层要发消息
@Override
public void run() {
String tname=Thread.currentThread().getName();
//此方法要运行在handler关联的looper所在的线程
System.out.println(tname+"-->run()");
}
});
Looper.loop();
}
}