
注:以下内容基于Android API Version 27(Android 8.1)Linux Kernel 3.18.0
Toast的显示与消失
Toast的创建和显示是发生在App进程,而Toast何时显示何时消失是由NotificationManagerService控制的。
一个Toast从创建到显示再到消失有着如下过程:
- 通过
makeText创建一个Toast对象,创建Toast对象主要是创建了Toast的View。 - 调用
Toast对象的show方法,show方法调用了NotificationManagerService的enqueueToast将Toast内部的一个实现了ITransientNotification的名为TN的Binder本地对象传给了NotificationManagerService,并传递了Toast的持续时间。 NotificationManagerService运行于system_server进程,负责管理系统中所有的Toast,NotifactionManagerService逐个处理队列中的Toast,为Toast创建一个token(new Binder())并添加到WMS(调用addWindowToken),WMS会为之创建一个WindowToken并记录到tokenMap。NotifactionManagerService回调Toast的TN的show方法,将token传递给App进程的Toast对象。- App进程的
Toast对象通过Handler转到主线程执行WindowManager(WindowManagerImpl)的addView将Toast的View添加到WMS从而将自己显示出来,这中间包括了ViewRootImpl的逻辑。 - 当显示时间到达后
NotificationManagerService回调TN的hide方法进而由App进程调用WMS移除Toast。
总结
1, NotificationManagerService统一管理系统中所有Toast的显示与消失,Toast真正的显示和消失操作由App进程的Toast对象执行,这点和ActivityManagerService之于Activity的思路是一致的。
2,Toast的窗口类型是TYPE_TOAST,TYPE_TOAST是一种system window,Toast有自己的token,不受Activity的控制。
3,Toast直接将自己的View添加到WindowManagerImpl而没有创建PhoneWindow和DecorView,这点和Activity/Dialog有所区别,Toast View的事件(如果有)是直接派发到Toast的View tree的。