2016-04-21 49 views
3

將Dexguard從7.0.12更新到7.1.22後,我遇到了Enum開關的崩潰。Dexguard/Proguard使應用程序在Enum開關上崩潰

這隻發生在Dexguard已經運行在我們的項目上(我想這是由Proguard問題引起的)。

如果我使用硬編碼值,則不會發生崩潰。

Of course,我想避免使用硬編碼值。

碰撞

發生是以下

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

這發生在,指出switch(type) {行碰撞(見下文)

一些示例代碼在其上該應用程序崩潰(鑑於MyEnum是一個Enum ofcourse):

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

但是這不能解決問題。

UPDATE

我只是檢查映射文件,我所有的枚舉名稱等的保存。現在我對發生的事情更加無知。

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.$的事實令我煩惱。這看起來不正確。或者是正常的?

UPDATE 4

剛剛回復我們的舊版本Dexguard並且去除了我添加Proguard的規則。

現在不再發生崩潰,儘管代碼仍然看起來完全一樣。 (中間體和完全編譯代碼)

更新5

切換到Dexguard 7.2和它去無瑕。

+0

你能聯繫[email protected]這個問題,包括你的配置文件和apk進一步調查? –

回答

1

switch語句將創建一個數組字段$SwitchMap$MyEnum將enum字段的序數映射爲大於0的整數。您需要確保保留此類和它的字段。

+0

我該怎麼做或檢查這個? – SnyersK

+0

@SnyersK查看* build/intermediates/classes *文件夾中創建的類文件。它應該是一個匿名的內部類。然後找出proguard是否刪除了該課程或該領域。此外,知道「Lif」究竟是什麼會很有趣。 – tynn

+0

剛剛更新了我的問題與中間代碼 – SnyersK