将Dexguard从7.0.12更新到7.1.22后,我在Enum开关上遇到崩溃。

这仅在Dexguard在我们的项目上运行时发生(我想这是由Proguard问题引起的)。

如果我使用硬编码值,则不会发生崩溃。

当然,我想避免使用硬编码值。

迷恋;撞车;崩溃

发生的崩溃如下

java.lang.NoClassDefFoundError: Failed resolution of: Lif;

这发生在声明switch(type) {的行上(请参见下文)

例子

应用程序崩溃的一些示例代码(假设MyEnum是类(class)的Enum):
MyEnum type = MyEnum.SomeValue;

switch (type) {
    case SomeValue:
        // Do something
        Log.i("Tag", "Hello world!");
        break;
}

假设MyEnum.SomeValue的序数值为1。

如果我将case SomeValue:更改为case 1:,它会按预期工作。

我尝试过的

我不知道为什么会发生此崩溃。我试图添加这些Proguard规则。
-keep enum * { *; }
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

但这不能解决问题。

更新

我只是检查了映射文件,所有枚举名称都保留了。现在,我对所发生的事情一无所知。
my.identifier.MyEnum -> my.identifier.MyEnum:
    my.identifier.MyEnum SomeValue -> SomeValue
    my.identifier.MyEnum[] $VALUES -> $VALUES
    6:6:my.identifier.MyEnum[] values() -> values
    6:6:my.identifier.MyEnum valueOf(java.lang.String) -> valueOf
    6:6:void <init>(java.lang.String,int) -> <init>
    6:7:void <clinit>() -> <clinit>

更新2

只是看了看输出。它已编译为此。
从堆栈跟踪来看,我认为if不被Proguard保存。
在哪里定义?我需要添加什么才能使Proguard保持此状态?
switch(if.ˊ[var2.ordinal()]) {
    case 1:
        //some other code
        break;

更新3

在中间代码行看起来像这样:
switch(null.$SwitchMap$my$identifier$MyEnum[type.ordinal()]) {
    case 1:
        //some other code
        break;

它声明null.$的事实困扰着我。这似乎是不对的。还是正常?

更新4

刚刚恢复到我们的旧版Dexguard,并删除了我添加的Proguard规则。

尽管代码看起来仍然完全相同,但现在不再发生崩溃。 (中间体和完全编译的代码)

更新5

切换到Dexguard 7.2,一切顺利。

最佳答案

switch语句将使用数组字段$SwitchMap$MyEnum创建一个合成内部类,该数组类将枚举字段的序数映射为大于0的整数。您需要确保也保留了该类及其字段。

关于android - Dexguard/Proguard使应用程序在Enum开关上崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36775749/

10-12 00:11
查看更多