handler机制原理

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();
    }
}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值