WindowManger详解
更新
直播回放已放出,请戳链接食用:不使用Activity如何添加一个View
整体方案
在Service中通过WindowManger添加View的方式来把UI界面显示出来
业务场景
具体场景
- IQOO手机,游戏辅助
这种场景能否使用Activity方式来做
使用activity会对下层window产生阻塞,而使用WindowManager添加view的方式则不会阻塞
WindowManger简介
WindowManger是普通App进程用来与系统服务(WindowMangerService)通信的一个接口。
获取WindowManger实例对象的方法是使用Context.getSystemService(Context.WINDOW_SERVICE
)
如何使用
- 添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
复制代码
-
手动引导开启
显示在其他应用上层
-
获取WindowManger并添加View
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); //获取系统服务
windowManager.addView(myView, p);
复制代码
- 不使用时移除View
WindowManager使用详解
WindowManger
- 添加View :
addView()
注意 同一个window,只能添加一个View,添加多个View会报出以下异常
Caused by: java.lang.IllegalStateException: View android.widget.RelativeLayout{b3a2c6a V.E...... ......I. 0,0-0,0 #7f070081 app:id/rl_root} has already been added to the window manager.
复制代码
- 移除View :
remoview()
由于同一个View只能添加一个View,所以,要想在已添加View的Window中再添加View,必须先移除已添加的View
- 更新布局属性 :
updateViewLayout(view,params)
通过对第二个参数WindowManger.LayoutParams的属性设置后,调用本方法才会使这些属性生效
WindowManger.LayoutParms
WindowManger.LayoutParms
其实是ViewGrop.LayoutParms
的子类对象,所以View设置LayoutParams时可以直接设置
- 控制是否可以响应触摸事件
layoutParams.type
FLAG_NOT_TOUCHABLE
FLAG_NOT_TOUCH_MODAL
- 控制window的显示层级
layoutParams.type
TYPE_TOAST
(Andorid 5.0及以下系统版本可规避权限问题)TYPE_APPLICATION_WINOW
(应用层Winow等级)TYPE_PRIORTY_PHONE
(系统层Window等级)
- 控制view的显示范围
layoutParams.flags
FLAG_FULLSCREEN
FLAG_LAYOUT_IN_SCREEN
- 控制view的显示位置
layoutParams.width
layoutParams.height
示例项目
还要注意哪些问题?
- 使用单独进程,避免影响主业务功能
- 提升进程优先级,避免被Kill
- 使用前台服务
- 1像素保活
- 绑定系统服务
提示:可通过oom_adj查看某个进程的进程等级
- 要对服务被Kill后的重启逻辑进行处理
源码浅析
由于时间关系,这里我们只对相关源码进行一个简单的介绍,先来看下相关的类
WindowManger
这个类,其实只是一个接口,用来沟通普通应用进程和系统服务WindowMangerservice
我们在上面的使用中也看到了,获取WindowManger这个类的实例对象,是通过Context.getSystemServer(Context.WINDOW_SERICE)
获取的
通过上面的UML类图我们也可以看到,其实WindowManger是一个接口,而它的真正的实例对象是WindowMangerImpl
这个类
而WindowMangerImpl
又把具体的添加View的工作封装到了WindowManagerGlobal
中来操作,这个类中又涉及到了另外一个重要的类--Display
,这个类主要是封装了一些显示相关的信息,比如window的逻辑宽显示数据(logical displays)和物理显示数据(physical displays)
什么是
logical displays
源码中对此解释是,逻辑显示不一定代表特定的物理显示设备,例如内置屏幕或外接显示器。 逻辑上的内容根据设备的不同,显示屏可以显示在一个或多个物理显示屏上
什么是
physical displays
就是Android设备屏幕的真实的Displays数据,比如你的手机是4K的屏幕(physical displays),但是厂商为了进行一些优化工作(比如省电?)可以把显示尺寸(logical displays)设置为1920* 1080
郑重声明
本文版权归Android研习社
所有,未经允许禁止转载,侵权必究!