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 中删除: