Toast 源码实现 (完结)

作者: 周俊devin | 来源:发表于2016-05-28 10:17 被阅读553次

        1. 从构造函数来看, 构造函数做的事情有: 

    --> 指定 Toast 对应的 context 环境 --> 创建 TN 提供给 ToastManagerService 的 binder 接口. --> 获取到 系统指定的在 Y 位置 上的 偏移像素.

        2. 针对 Toast的使用, Toast 类提供了一个 工具构造方法 Toast.makeText():  ------ > 从 这个 地方我们 可以知道 通过  调用 setView() 来完成对 mNextView 进行赋值,  来达到 自定义 layout 的目的.

    --> 创建 Toast 对象. --> 获取LayoutInflater, 然后 渲染 出 layout 文件 transient_notification 文件 对应的 View 树形图. 并对其中  R.id.message 对应的 TextView 进行赋值. --> 将 inflate 获取到的 View 设置到 result 的 mNextView 这个属性上. --> 设置 Toast 对应的 View 的展示时间. 有 LENGTH_LONG(3.5s) 和 LENGTH_SHORT(2s)

        3. 使用 Toast.makeText() 只是 获取到 一个 Toast 对象, 那么我们怎么展示它呢? 这就用到了 Toast 的 show() 方法了.

    --> 获取 INotificationManager 对应的 service 的引用. --> Toast 中的 mNextView 赋值给 TN 对象的 mNextView 这个属性上. --> 调用   INotificationManager 对应的 service 把 tn 放到 对应的 Toast 队列中. 

        4. enqueueToast 的实现逻辑为:

    根据传入的 pkg 判断是否是系统Toast, 然后 在 mToastQueue 上加同步锁, 然后 根据 pkg 和 callback (即 TN 对象的引用 来查询是否已添加过这个Toast).

    当 mToastQueue 中 没有 这个 Toast 对应的 ToastRecord 的时候, 则重新创建一个 ToastRecord 添加到 mToastQueue 这个队列中, 当 判断队列中只有 一个 ToastRecord 时,则 调用 showNextToastLocked() 方法用来展示 Toast.

        5 在 showNextToastLocked() 中 会先从 mToastQueue 中 取出 ToastRecord, 然后 调用 ToastRecord 对应的 callback (即 TN ) 中的 show() 方法显示视图.

        

    第一部分:  分析 show() 方法.

    其中 TN.show() 的实现为:
        
    其中 mShow 对应的 Runnable 中的 run() 方法实现为:      


    在 handleShow() 中 会把 mNextView 设置 给 WMS 用于 展示.

    第二部分: 分析超时

    在 showNextToastLocked() 还会设置 一个超时监听.
    当 Toast 的显示时机 到 long_delay 或 short_delay的时候 回调  MESSAGE_TIMEOUT 对应的 msg 事件.

    则 handleMessage() 的实现为: 会尝试 调用 handleTimeout 对应的方法, 并把 ToastRecord 作为参数传入.


    如果 能在 mToastQueue 中查询到 对应的 Toast 则 调用取消逻辑:

    在 cancelToastLocked() 方法中, 会先 调用 TN 中的 hide() 方法, 然后 将 ToastRecord 从 mToastQueue中 移除,  然后判断 mToastQueue中是否还有 其他的ToastRecord ,如果有 则 调用 showNextToastLocked() 进行处理.

    其中 TN.hide() 做的事情 很简单,就是 把 View 从 WMS 中删除:

    相关文章

      网友评论

        本文标题:Toast 源码实现 (完结)

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