Handler

    技术2022-06-29  74

    ps:部分java的源代码代码是通过反编译得到的。

    如果自定义的handler使用的每个线程不能确保是长生命周期的,就不需要使用自定义的Looper,而直接使用 mMainLooper:Looper.getMainLooper()。

     

    1.handler的学习

    ActivityThread是应用程序的主线程,通过Looper.prepare()【得到消息队列looper】和Looper.loop()【死 循环读取looper】,使得主线程能够一直running。

    实现Looper机制的另外一种方案可以参照RIL.java

            mSenderThread = new HandlerThread("RILSender");         mSenderThread.start();

            Looper looper = mSenderThread.getLooper();         mSender = new RILSender(looper);

    ps:任何进程的UI主线程几乎都是这么设计的。

     

    2.Handler的消息对象的引用

    sendMessage,其实是向Hander绑定的looper的MessageQueue中加入一条message而已。

     

    3.Looper类:Looper的构造函数是私有的,只能通过prepare构造;一个线程只能有一个Looper,其实就是把looper对象的引用 放到当前thread对应的threadLocals(map:key is sThreadLocal,value is looper)中,当该线程再次创建Looper对象时,通过查询当前线程的threadLocals map 的key sThreadLocal对应的value是否为空,即可知道当前Thread是否已经创建过prepare的Looper对象。

    Looper.prepareMainLooper():prepare()方法+设置mMainLooper

    Looper都对应一个MessageQueue(Message的queue),可以查看Looper的源码

    Looper有一个静态成员变量ThreadLocal:private static final ThreadLocal sThreadLocal = new ThreadLocal();

    prepare():会调用sThreadLocal.set(new Looper());->threadlocalmap.set(this, obj);

    ps:确保thread的threadLocals map存在,this即是是sThreadLocal。

    myLooper():调用(Looper)sThreadLocal.get();->如果当前thread存在 threadLocals,ThreadLocalMap.Entry entry = threadlocalmap.getEntry(this);if(entry != null) return entry.value;否则调用setInitialValue();其实就是返回null。

    ps:this即是sThreadLocal。

     

    4.Thread:成员引用变量ThreadLocal.ThreadLocalMap threadLocals;


    最新回复(0)