Android悬浮窗导致其它应用黑屏问题解决办法
背景
项目需要做一个悬浮窗,用于控制一个后台服务,但是发现开启该服务之后某些应用会黑屏,具体体现就是只有一个悬浮窗,然后整个屏幕都是黑的。
排查
原以为是后台服务导致的,于是在应用商店下载了有类似后台服务的应用程序进行对比,发现均未出现这种现象,还在github上找了使用了类似后台服务的开源项目对关键代码进行了比较,并对不同点进行了对照试验,发现均未能解决问题;之后才想到可能是悬浮窗的问题,于是屏蔽了悬浮窗显示逻辑,这才确认了是悬浮窗的问题。
问题解决
该问题的根本是WindowManager.LayoutParams
的format
属性设置问题,设置这个属性是因为我的悬浮窗是组合了多个基本组件,比如按钮,文本框,将悬浮窗添加到桌面上时,背景默认是黑色的。
为此我将format
属性设置为PixelFormat.RGBA_8888
,此时背景确实变成透明的了,但是就引发了本文的问题,在某些应用上显示这类悬浮窗时,应用窗口就变成全黑了。
问题的根本原因是因为WindowManager.LayoutParams
的format
属性默认是PixelFormat.OPAQUE
,而源码中对该属性的说明是:
java
/** System chooses an opaque format (no alpha bits required) */
public static final int OPAQUE = -1;
可以看到,因为默认没有alpha
通道,所以背景为黑色,但是又不能设置为PixelFormat.RGBA_8888
,那么怎么办呢?答案是继续看源码,PixelFormat
源码:
java
public static final int UNKNOWN = 0;
/** System chooses a format that supports translucency (many alpha bits) */
public static final int TRANSLUCENT = -3;
/**
* System chooses a format that supports transparency
* (at least 1 alpha bit)
*/
public static final int TRANSPARENT = -2;
/** System chooses an opaque format (no alpha bits required) */
public static final int OPAQUE = -1;
可以看到,TRANSLUCENT
只是要求具备alpha
通道,但是具体几位并未限制,而TRANSPARENT
则要求至少1位alpha
通道,那么将format
属性设置为PixelFormat.TRANSLUCENT
能不能行呢?
答案是可以的,也就是本文最终的解决方案:
将format
属性设置为PixelFormat.TRANSLUCENT
即可完美兼容悬浮窗和这类黑屏应用。