美文网首页
Handler从源码角度分析实现原理

Handler从源码角度分析实现原理

作者: 一束佛光 | 来源:发表于2021-01-11 14:31 被阅读0次

    至尊宝是真真的爱着紫霞仙子。  -- 题记

    先看下测试代码:

    从上图可知mHandler是在onCreate的主线程执行的;mInnerHandler是在子线程执行的;

     1、从handler的源码角度看看handler是如何执行的

    1.    从handler的构造器可知,每新建一个Handler对象会重新生成一个looper对象;通过mLooper会生成一个消息池MessageQueue;也就是说一个Handler对象对应一个Looper对象,一个Looper对应一个消息池;

    1.1    那么myLooper方法是如何生成Looper的呢?

        ThreadLocal 源码注释中有很清楚的解释:它是线程的局部变量,这些变量只能在这个线程内被读写,在其他线程内是无法访问的。get方法   是ThreadLocal 里的一个方法,

     从当前线程获取map,从map里获取Looper;;

    截下来看下getMap()方法是怎么获取到ThreadLocalMap的

    他是Thread线程里的一个方法,这里说明了在哪个线程里创建的handler对象,handlerMessage就在哪个线程;一个线程只有一个Looper、只有一个MessageQueen,只有一个只供当前线程使用的ThreadLocal ;

    ThreadLocal 有get()方法,那么他也一定要set方法;

    这回知道为什么在线程里new Handler对象要调用Looper.prepare()了吧;

    2.为什么在OnCreate里,没有调用Looper.prepare ?

    我们看下ActivityThread这个类

    他这里已经调用了,启用的是主线程;这里还是是main方法,Activity的OnCreate还没有被调用,原因下次再说;

    截下来我们看下 Looper.loop()方法;

    所以loop方法的调用肯定都是在一个方法的最后,因为这是一个死循环,执行这个方法就不再执行下边的任何步骤了;

    当前线程的Looper从消息队列读取消息,当读完所有消息时,进入睡眠,线程阻塞。线程往消息队列发送消息,并且往管道文件写数据,线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。

    那么他是怎么往消息队列里添加消息的呢?

    通过    mHandler.sendEmptyMessage(1);这类的方法,通过mHandler.sendxxxxxMessage源码我们可知道,他们最终调用的都是sendMessageAtTime方法

    这里最终调用的是消息池的enqueueMessage方法,将消息添加到队列,根据message对象的when的值将消息排队,然后唤醒当前线程继续轮询;

    Looper.loop()方法里的for死循环里将消息分发出去

    msg.target.dispatchMessage中的target点进去其实就是Handler对象,它调用自己的HandleMessage方法将其回调出去

    总结

    if ( 从onCreate里new Handler){

            在ActivityThread的main()方法中存入了Looper.prepareMainLooper();(这里已经创建了Looper,messagequeue)

    } else {

            每次在新的线程创建Handler对象 需要调用Looper.prepare();逻辑执行完还要调用Looper.loop();去启动消息池的轮询;

    }

    new Handler的时候Handler就已经拿到了线程的Looper 。MessagQueue

    handler发送消息:

    把Handler保存到Message里。

    把Message保存到messageQueue里。

    然后不断地执行获取消息的方法:Looper.loop();去出message,然后调用handler的dispatchMessage(msg),消息回调到当前handler的handleMessage里;

    相关文章

      网友评论

          本文标题:Handler从源码角度分析实现原理

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