首页 > 解决方案 > onCloseSystemDialogs shrinkResources 问题

问题描述

我有一个支持显示覆盖屏幕的应用程序(使用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_BACKcall 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.**

标签: androidproguard

解决方案


这是一个有效的解决方案

添加到proguard-rules

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

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

所以,创建一个新类

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

    public void onCloseSystemDialogs(String reason) {
    }
}

Then instantiate wraper like this:

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
            }
        }
    };

推荐阅读