当前位置: 首页 > 知识库问答 >
问题:

Dexguard/Proguard使应用程序在枚举开关上崩溃

壤驷穆冉
2023-03-14

在将DexGuard从7.0.12更新到7.1.22之后,我遇到了Enum交换机崩溃。

只有当DexGuard在我们的项目上运行时才会发生这种情况(我想这是由ProGuard问题引起的)。

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

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

发生的崩溃如下

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

这发生在说明开关(类型){的行上(见下文)

应用程序崩溃的一些示例代码(鉴于MyEnum当然是Enum):

MyEnum type = MyEnum.SomeValue;

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

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

如果我改变大小写:大小写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>

只是看了一下输出。它被编译成这样。根据堆栈跟踪判断,我认为如果没有被ProGuard保存。这个定义在哪里?我需要添加什么才能让ProGuard保留这个?

switch(if.ˊ[var2.ordinal()]) {
    case 1:
        //some other code
        break;

在中间产品中,该代码行如下所示:

switch(null.$SwitchMap$my$identifier$MyEnum[type.ordinal()]) {
    case 1:
        //some other code
        break;

事实上,它声明null.$困扰着我。这似乎不对。或者这正常吗?

刚刚恢复到旧版本的DexGuard,并删除了我添加的ProGuard规则。

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

切换到DexGuard 7.2,它完美无瑕。

共有2个答案

尉迟龙光
2023-03-14

我也有同样的问题。当我反编译类时,我看到问号(?在本例中应为arg0)

public static cr a(String arg0)
  {
    switch (???)
    {
    case "caseOne": 
      ??? = a;
      break;
    case "caseTwo": 
      ??? = f;
      break;
    default: 
      ??? = null;
    }
    return (cr)???;
  }

如果你在内部重新分配论点

arg0= arg0.toLowerCase();

然后proguard知道该放什么而不是问号

public static cr a(String paramString)
  {
    switch (paramString = paramString.toLowerCase())
    {
    case "caseOne": 
      paramString = a;
      break;
    case "caseTwo": 
      paramString = f;
冷翼
2023-03-14

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

 类似资料:
  • 我在我的Android应用程序中使用GSON来解析数据。我已经在模型对象中添加了枚举。添加枚举后,我的应用程序开始崩溃。当我让runProguard假的时候,一切都很好。当程序是真的时,我做了我能在网上找到的一切来修复这个问题。但还是没运气。 我已经在proguard-rule文件中做了以下事情 枚举材料示例: 我的堆栈跟踪

  • 问题内容: 每次我从Eclipse导出签名应用程序并将apk文件安装到手机上时,该应用程序都会崩溃。这仅在启用Proguard的情况下发生。 这是我的保护文件 我运行了adb logcat命令来检查崩溃报告。以下是我认为很重要的报告摘要: 第二段: 如果有人可以帮助我,我将非常感谢并接受您的回答。 更新: 所以我将这些添加到我的proguard文件中 现在启用Proguard时出现与Jackson

  • 谈到flexjson库,我在使用dexguard时遇到了问题。在尝试使用JSONDeserializer反序列化时,我一直遇到以下错误。 是否有人有适当的规则,flexjson在Android发布apks中混淆后正常工作? 类似于gson lib的东西。

  • 问题内容: 4年前关闭。 刚刚下载了Xcode 7 Beta,并列举了此错误 错误: 枚举不可用在序列上调用枚举方法 问题答案: 在Swift 2中,它不再是全局函数,而是的扩展。 直接在序列上调用它以进行枚举,如下所示:

  • 测试环境 用于运行Appium的桌面操作系统/版本:1.2.0-beta版。3(1.2.0-beta.3)节点。js版本(除非使用Appium.app | exe):移动平台/测试版本:ios模拟器iPhone 6s plus 10.2 1.从源树中提取最新代码 2.打开xcode 3.made存档文件 4.从那里获取应用程序文件。 5.openedAppium桌面应用 6.添加了所需的功能 应用

  • 我正在尝试检查我的VO中设置了哪些值。 下面是我的女儿。我得到的是“合格的病例标签MyEnum.UserType.Doctors必须替换为不合格的枚举常量Doctors” EnumTest.java