美文网首页
Handler-Message-Looper核心原理

Handler-Message-Looper核心原理

作者: 菠萝好吃 | 来源:发表于2020-07-23 14:25 被阅读0次

    核心部分

    核心有两个部分:调用通知者发送Message和Handler所在线程接受处理Message

    1.发送Message

    Handler是调用的核心类。

    *使用Handler.sendMessage()发送message消息

    *Handler中调用当前线程的looper.enqueueMessage

    *MessageQueue插入Message;

    以上就完成了发送message基本操作。

    2.接收处理Message

    Looper为核心中转控制。

    *Looper.Loop()开启一个死循环。

    *循环中等待MessageQueue返回message

    *有返回,则通过msg.target.dispatchmessage回调给Hanlder以及调用者;

    以上完成接收处理Message。

    细节详解

    1.发送Message细节

    *Handler中通过sendMessage()发送message消息,也能通过post(Runnable r),本质上post中,也是把Runnable进行一层封装,多了一个回调;

    *Handler使用Looper类时,并不是直接new,而且通过Looper.myLooper();

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

    public static @Nullable Looper myLooper() { return sThreadLocal.get();}

    使用了ThreadLocal,不同线程取到不同Looper实例,一个Looper实例对应一个MessageQueue列表;做到了线程间的消息队列隔离

    *MessageQueue类中通过Message的next属性,将他们组成一个单向链表。enqueueMessage将Message加入队列。如果Message没有特殊就直接加入队列尾,而如果前面Hanlder中使用了sendMessageDelayed,指定了时间,则会在遍历链表过程中,选择合适点插入,此处有用到Message的when属性。

    另外一个很重要点,enqueueMessage中遍历循环后,需要判断是否要唤醒队列,主要根据当前是否mBlocked堵塞。唤醒使用nativeWake()。此方法对应nativePollOnce(),都是C层原生方法 。类似Object的notify()和wait(),但底层原理又有所不同。

    2.接收处理Message细节

    Looper.Loop()开启一个死循环,在for循环中不断调用Looper.MessageQueue.next()等待返回message。

    next()中,通过nativePollOnce()进行等待。nativePollOnce()本质关键为使用linux中的epoll多路IO复用。

    等待返回message后,msg.target.dispatchmessage回调给Hanlder以及调用者。

    最后继续循环等待。

    3.总结

    Hanlder为一个对外封装类,方便调用者使用。

    Looper找到当前线程的MessageQueue和开启Loop循环。

    MessageQueue消息队列,管理插入Message和返回Message,等待和唤醒实现都是c层。


    相关文章

      网友评论

          本文标题:Handler-Message-Looper核心原理

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