由于Launcher卡片是用WindowManager. addView(card)的方式,添加到屏幕上(卡片是系统窗口),这导致与其他系统弹窗(激活对话框、输入法对话框等)的显示层级会发生冲突。具体现象如下:


根据需求文档,期望的各个浮窗的层级定义如下:
期望层级:

实际层级:

从上面明确问题过程中,可以推导出:如果能降低Launcher卡片的显示层级。即降低到和地图一样的层级,使得卡片的生命周期能跟随地图Activity一致,随地图显示和隐藏,则可以让其他对话框都浮在Launcher卡片上面。即做成地图Activity上的一个PopupWindow。
方案一:直接添加应用层窗口, 需要获取导航进程的token。
方案二:导航以AAR的方式集成卡片。需要调整launcher其他模块和卡片的通信方案,改动比较大。
方案三:launcher留出容器,加载导航的activity。
临时方案都可能导致其他问题,综合考量,选择了侵入性小的永久实施方案一:
Launcher卡片SDK提供AIDL接口,导航通过这个接口,把它的activity的token传到Launcher进程来,Launcher以wm.addView()的方式,把window token设置这个acitivityToken,就可以把卡片显示成地图的子窗口了。
[This type of content is unavailable for download at the moment.]
获取activity的token代码如下:

测试效果:

解决问题过程中,最关键的是明确问题,发现问题的规律。这里就是卡片层级问题。当发现用activity级别的window type时, 会报bad token的异常,可推导出系统添加window需要一个token。查看源码发现token就是一个binder对象,所以我们可以把地图activity的token通过binder通信传递到Launcher这边来。