正常情况下,我们的dialog创建必须传入Activity的context上下文。否则会报错:token null is not valid;is your activity running?
为何如此,dialog是window,是window就要符合系统WMS的协调和管理。
Window的类型
Window 的类型有很多种,比如应用程序窗口、系统错误窗口、输入法窗口、PopWindow、Toast、Dialog 等。总的来说 Window 分为三大类型:
- Application Window(应用程序窗口):取值在 FIRST_APPLICATION_WINDOW和LAST_APPLICATION_WINDOW 之间。 是通常的、顶层的应用程序窗口,必须将token设置成activity的token。
- Sub Window(子窗口):取值在 FIRST_SUB_WINDOW和 LAST_SUB_WINDOW 之间。 与顶层窗口相关联,token必须设置为它所附着的宿主窗口的token。
- System Window (系统窗口):取值在 FIRST_SYSTEM_WINDOW和LAST_SYSTEM_WINDOW 之间。 用于特定的系统功能。它不能用于应用程序,使用时需要特殊权限。
每个大类型中又包含了很多种类型,它们都定义在 WindowManager 的静态内部类 LayoutParams 中。
应用程序窗口
应用程序窗口是特定应用程序内部存在的窗口,可以是全屏窗口或者普通窗口。应用程序窗口的类型由 WindowManager 类的常量值定义,其 Type 值范围为 1~99,代表着窗口的层级。应用程序窗口可以对应应用程序内不同的 Activity,可以进行添加、删除、修改等操作。
例如:
TYPE_APPLICATION:应用程序窗口,占据整个屏幕。
TYPE_APPLICATION_PANEL:应用程序面板窗口,在应用程序窗口之上,但能被覆盖。
TYPE_APPLICATION_ATTACHED_DIALOG:应用程序附加对话框窗口,与父 Activity 关联,当 Activity 消失时会自动消失。
TYPE_APPLICATION_MEDIA:应用程序媒体窗口,用于播放视频和音频。
子窗口
子窗口是依附于父窗口之上的窗口,不具有独立性。子窗口的类型也由 WindowManager 类的常量值定义,其 Type 值范围从 1000~1999。子窗口是建立在应用程序窗口之上的,也就是说,他们必须依附于某个应用程序窗口之上,但是他们可以通过 WindowManager.LayoutParams 类的相关参数(如 parent、token 参数)来改变自己的层级,从而达到弹出效果。
例如:
TYPE_APPLICATION_SUB_PANEL:应用程序子面板窗口。
TYPE_APPLICATION_TOP_MOST:应用程序最顶层窗口。
TYPE_SYSTEM_ALERT:系统警告窗口,显示系统级的警报信息,例如低电量警告。
TYPE_TOAST:提示窗口,用于显示简短的消息。
系统窗口
系统窗口是系统级别的窗口,通常用于显示系统级别的信息或者对话框,例如 Toast、输入法窗口、系统音量条窗口等。它们都属于系统级别的应用程序,具有比较高的优先级和权限。系统窗口的类型也由 WindowManager 类的常量值定义,其 Type 值范围为 2000~2999。相对于应用程序窗口和子窗口,系统窗口的层级最高,因此它们总是能够出现在屏幕的最上层,即使是该应用程序的活动窗口正在显示中。
例如:
TYPE_STATUS_BAR:状态栏窗口,显示系统状态,例如时间、电量等。
TYPE_NAVIGATION_BAR:导航栏窗口,是一个系统级别的窗口,用于控制屏幕导航。
TYPE_INPUT_METHOD:输入法窗口,显示用户输入的文本。
TYPE_SYSTEM_OVERLAY:系统覆盖窗口,它可以放置在所有其他窗口的上面。
在非Activity对象创建并正常显示Dialog
正常情况下,我们创建的dialog都是子窗口,子窗口是依赖于应用程序窗口的,所以需要传入Activity的context上下文。
如果我们需要在Service中弹出dialog,可以创建系统window。
- 需申请SYSTEM_ALERT_WINDOW权限
- 在调用Dialog.show方法之前,必须把Dialog的Window的type指定为SYSTEM_WINDOW的类型,比如TYPE_SYSTEM_ALERT或TYPE_APPLICATION_OVERLAY。
————————————————
参考链接:
https://blog.csdn.net/qq_43358469/article/details/131121966
Android老司机被打脸!Dialog 对应的 Context 必须是 Activity吗?_mb648c193277ba0的技术博客_51CTO博客