Handler原理解析

作者: feary | 来源:发表于2016-10-14 01:05 被阅读184次

    首先从Handler 的构造方法开始,Handler有几种构造方法,先从最开始的最普通的开始,Handelr handler = new handler();

    点进去 看源码:

    publicHandler() {

        this(null,false);

    }

    进去后回发现其中调用了

    mLooper= Looper.myLooper();

    mQueue=mLooper.mQueue;

    即会添加该线程上对应的一个Looper对象,然后拿到该线程对应的MessageQueue,将创建的handler与该Looper绑定成对应关系,其中Looper是通过ThreadLocal(java的一个类,可以通过它得到一个线程与相应变量的Map,即通过它实现了Looper线程的唯一性)实现与每个线程做绑定一一对应的,即每个线程可通过ThreadLocal拿到其对应的那个Looper(前提是有),即一个线程最多对应一个Looper,而每个Looper又管理一个消息队列(MessageQueue),而Handler即负责把消息传给队列的,消息为Message,是谷歌封装的一个消息类,里面可以传普通的东西,也有callBack,你想让handlerMesage的执行在哪个线程,就要把消息扔到对应线程的MessageQueue里,而最开始构造方法里就是会有对handler里设置其对应的MessageQueue,即创建它的线程上执行。其中也有其他的构造方法,可以把其他线程对应的Looper设进去,实现在另一线程上运行。那么为什么塞到对应的MessageQueue里就可以在对应线程上执行了呢?因为Looper所谓对应一个线程,是指Looper在创建时会立刻执行loop方法,即loop方法是在其对应的那个线程上执行的,loop方法逻辑理解上比较单纯,即是一个死循环不停地从MessageQueue里拿数据,一旦有Message来了,就会在该线程执行里面的之前post进来的Runnable,或者对Message执行对应HandleMessage,即handler只是在子线程把消息放进消息队列里,然后系统时间片轮转时切换线程,继续死循环遍历MessageQueue,一旦来了就执行,即最后执行是在loop的线程上,即Looper创建的那个,即其对应的那个线程。

    Handler把消息扔进消息队列,message会存有该Handler的引用,这样在从消息队列抽出来时,消息会被其对应的Handler执行。

    最后一个,即为什么loop这个死循环会在主线程执行,不会ANR么?答,最开始Android的入口ActivityThread里面的main方法,里面有一个巨大的Handler,然后会创建一个主线程的looper对象,这也是为什么直接在主线程拿Handler就有Looper的原因,在其他线程是要自己Looper.prepare()的。其实整个Android就是在一个Looper的loop循环的,整个Androidi的一切都是以Handler机制进行的,即只要有代码执行都是通过Handler来执行的,而所谓ANR便是🈯️Looper.loop没有得到及时处理,一旦没有消息,Linux的epoll机制则会通过管道写文件描述符的方式来对主线程进行唤醒与沉睡,android里调用了linux层的代码实现在适当时会睡眠主线程。

    相关文章

      网友评论

        本文标题:Handler原理解析

        本文链接:https://www.haomeiwen.com/subject/fydgyttx.html