Android悬浮窗导致其它应用黑屏问题解决办法

Android悬浮窗导致其它应用黑屏问题解决办法

背景

项目需要做一个悬浮窗,用于控制一个后台服务,但是发现开启该服务之后某些应用会黑屏,具体体现就是只有一个悬浮窗,然后整个屏幕都是黑的。

排查

原以为是后台服务导致的,于是在应用商店下载了有类似后台服务的应用程序进行对比,发现均未出现这种现象,还在github上找了使用了类似后台服务的开源项目对关键代码进行了比较,并对不同点进行了对照试验,发现均未能解决问题;之后才想到可能是悬浮窗的问题,于是屏蔽了悬浮窗显示逻辑,这才确认了是悬浮窗的问题。

问题解决

该问题的根本是WindowManager.LayoutParamsformat属性设置问题,设置这个属性是因为我的悬浮窗是组合了多个基本组件,比如按钮,文本框,将悬浮窗添加到桌面上时,背景默认是黑色的。

为此我将format属性设置为PixelFormat.RGBA_8888,此时背景确实变成透明的了,但是就引发了本文的问题,在某些应用上显示这类悬浮窗时,应用窗口就变成全黑了。

问题的根本原因是因为WindowManager.LayoutParamsformat属性默认是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即可完美兼容悬浮窗和这类黑屏应用。