关于Activity/Dialog/PopupWindow/Toast的Window总结

3,419 阅读1分钟

注:以下内容基于Android API Version 27(Android 8.1)Linux Kernel 3.18.0

概括

ActivityDialogPopupWindowToast代表着四种典型Window形式。

  • Activity的Window类型是TYPE_APPLICATION,在WMS有一个唯一的AppWindowToken与之对应。

  • Dialog的Window类型也是TYPE_APPLICATION(Dialog不是子窗口),Dialog和其所在的Activity共用一个AppWindowToken

  • PopupWindow的Window类型是TYPE_APPLICATION_PANELTYPE_APPLICATION_PANEL是子窗口的一种,PopupWindow和其所在的Activity共用一个AppWindowToken

  • Toast的Window类型是TYPE_TOASTTYPE_TOAST是系统窗口的一种,Toast的token是由NotificationManagerService创建的,每个Toast对应一个自己的token,Toast的token在WMS对应的是WindowToken。

PhoneWindow/DecorView/ViewRootImpl

PhoneWindow包含一个DecorViewActivity的content view是DecorView的一个子ViewDecorView是content view套用模板(窗口样式)后的根View

一个DecorView对应一个ViewRootImplViewRootImpl是一个虚拟的根View,本身不是ViewViewRootImpl负责处理View tree 发生的更新请求,同时肩负着与WMS通信和输入事件的派发。

ActivityDialog都对应一个PhoneWindow对象。PopupWindowToast没有对应的PhoneWindowActivity/Dialog由于有PhoneWindow因此就有了DecorViewDecorView可以通过Window.Callback将输入事件派发给Activity/Dialog。 而PopupWindow/Toast都是用一个ViewGroup作为窗口的View,因此PopupWindow/Toast本身不具备获取输入事件的能力,输入事件是直接派发到了View tree。由于PopupWindow/Toast也是通过WindowManagerImpl添加的窗口,因此他们都有对应的ViewRootImpl, 因此也就具备了与WMS通信和事件派发的能力。

Activity/Dialog/PopupWindow/Toast与WindowState

Activity/Dialog/PopupWindow/ToastWMS都有对应的WindowState,只是Activity/Dialog/PopupWindow的WindowState属于同一个AppWindowToken,也就是Activity的token,而ToastWindowState属于自己独有的WindowToken