比较Activity和Dialog的窗口添加流程

之前在我的这篇blog中写到了Activity启动时activity / window /view之间的关系。大概的流程是,先创建activity,然后attach中执行window创建,接着setContentView中创建DecorView并且将DecorView和window进行绑定,接着在resume过程中通过将decorView添加到windowManager中WindowManager.addView(decor),在addView()方法中会创建ViewRootImpl供wm管理View树,在addView()的末尾会调用root.addView(decorView)最终将界面呈现出来。

Activity创建窗口显示过程

在这里插入图片描述

Dialog窗口添加流程

  • dialog创建
    • new Context
    • new Window(顺带创建了DecorView)
  • dialog.show()
    • dispatchOncreate()
    • onStart()
    • WM.addView()后面和Activity一样

另外,这里有一批总结性的文章可以参考下
https://www.jianshu.com/p/a50cbdeb1880

Android窗口类型

除了上面的Activity / Dialog(包括AlertDialog)外,Android还为我们提供了PopUpWindow,Toast等形式的弹框,这些弹框最后的展示都是通过调用wm.addView()来展示的。我们也可以自定义弹框,前面创建View,定义好窗口的LayoutParams,设置好窗口type,最后也可以通过wm.addView()来展示窗口。在这些窗口展示过程过,我们可能会遇到窗口添加失败的场景,这些失败在ViewRootImpl的setView()方法中都抛出了对应异常,提供给开发者debug信息。如下图所示:
添加view失败场景
分析上述常见错误之前,先来了解下android wm管理的窗口类型。Android将窗口分为三类:

  • Application window (应用窗口类型) 1~99
  • Sub-window(子窗口) 1000~1999
  • System window(系统窗口) 2000~2999

这三类窗口按照优先级从大到小,type越大,表示权限越高,能覆盖在其他type之上。
在这里插入图片描述
结合上面两张图,可以找到我们平时遇到的window添加失败的原因。

  1. 很多时候activity消失后弹框就会出现no token的情况,这个时候的做法是,dialog.show()之前判断activity是否已经或者正在finish(),如果是,此时不要弹出dialog(或者toast),避免crash。
  2. 自定义全局弹窗时,弹框与activity token无关,可以将dialog弹框type设置为系统弹框,如TYPE_APPLICATION_OVERLAY(6.0之后)/SYSTEM_ALERT_WINDOW(6.0之前),同时弹框之前需要动态请求SYSTEM_ALERT_WINDOW权限,否则会爆出权限错误。

窗口类型对应关系

窗口类型
ActivityTYPE_APPLICATION
DialogTYPE_APPLICATION
PopUpWindowTYPE_APPLICATION_PANEL
ToastTYPE_TOAST

一张图概况下这几种窗口的区别,来源
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值