整体方案
在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
文末
欢迎关注我的CSDN,分享Android干货,交流Android技术。
对文章有何见解,或者有何技术问题,都可以在评论区一起留言讨论,我会虔诚为你解答。
最后,如果你想知道更多Android的知识或需要其他资料我这里均免费分享,只需你多多支持我即可哦!
——可以直接点这里可以看到全部资料内容免费打包领取。