onCloseSystemDialogs shrinkResources 问题

onCloseSystemDialogs shrinkResources problem

我有一个应用程序支持显示覆盖屏幕(使用 SYSTEM_ALERT_WINDOW 权限)。

我实施了 KEYCODE_BACK 和主页新闻侦听器以删除其叠加视图。

val wrapper = object : FrameLayout(this) {
                override fun dispatchKeyEvent(event: KeyEvent): Boolean {
                    return when (event.keyCode) {
                        KeyEvent.KEYCODE_BACK -> {
                            deleteContentView()
                            true
                        }
                        else -> {
                            super.dispatchKeyEvent(event)
                        }
                    }
                }

                //if pressed home key,
                fun onCloseSystemDialogs(reason: String) {
                    //The Code Want to Perform.
                    deleteContentView()
                }
            }
contentView = LayoutInflater.from(this).inflate(R.layout.layout_overlay, wrapper)

它在 ProGuard 或 R8 未激活的调试模式下工作。 当我构建发布 apk 时,这个家庭新闻监听器不工作。

我不知道onCloesSystemDialogs()在应用程序中没有被任何其他方法调用,所以我让KEYCODE_BACK调用onCloseSystemDialogs,我想它不会再缩小了.

override fun dispatchKeyEvent(event: KeyEvent): Boolean {
                    return when (event.keyCode) {
                        KeyEvent.KEYCODE_BACK -> {
                            onCloseSystemDialogs("")
                            true
                        }
                        else -> {
                            super.dispatchKeyEvent(event)
                        }
                    }
                }

但是还是不行。无论如何让 Proguard 或 R8 不缩减这部分代码?谢谢。

这是我的build.gradle

buildTypes {
        debug {
            applicationIdSuffix '.debug'
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue "string", "app_name", "My app (Dev)"
        }
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            resValue "string", "app_name", "My app"
        }
    }

我的 ProGuard 文件

-keepattributes Signature
-keepattributes *Annotation*

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

##---------------End: proguard configuration for Gson  ----------

-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class * { *; }
-dontwarn javax.**
-keepnames public class * extends io.realm.RealmObject
-dontwarn io.realm.**

这是一个可行的解决方案

添加到proguard-rules:

-keepclassmembers public class * {
    public void onCloseSystemDialogs(java.lang.String);
}

但出于某种原因,仅将此规则添加到 proguard 是不够的,它一直将 onCloseSystemDialogs 标记为未使用的代码。

所以,创建一个新的 class

public class MyFrameLayout extends FrameLayout {
    //place here default constructors

    public void onCloseSystemDialogs(String reason) {
    }
}

然后像这样实例化wraper

MyFrameLayout wrapper = new MyFrameLayout(ctx) {
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                //do your stuff
                return true;
            }

            return super.dispatchKeyEvent(event);
        }

        @Override
        public void onCloseSystemDialogs(String reason) {
            if (reason.equals("homekey") /*|| reason.equals("recentapps")*/) {
                //do your stuff
            }
        }
    };