2016-04-21 3 views
3

После обновления Dexguard с 7.0.12 по 7.1.22 я столкнулся с сбоем в коммутаторе Enum.Dexguard/Proguard совершить крах приложения на коммутаторе Enum

Это происходит только тогда, когда Dexguard запускается в нашем проекте (я полагаю, это вызвано проблемой Proguard).

Если я использую жестко заданные значения, авария не возникает.

Конечно, я хочу избежать использования жестко заданных значений.

авиакатастрофы

Грохот, что происходит, является следующая

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

Это происходит на линии, которая заявляет switch(type) { (смотри ниже)

ПРИМЕР

Некоторые примеры кода, на котором приложение сбой (при условии, что MyEnum является перечислением):

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> 

UPDATE 2

Просто взглянули на выходе. Это скомпилировано. Судя по трассе стека, я полагаю, что if не хранится в Proguard. Где это определено? что мне нужно добавить, чтобы заставить Proguard сохранить это?

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

UPDATE 3

В промежуточных, что строка кода выглядит следующим образом:

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

тот факт, что он утверждает, null.$ беспокоит меня. Это не кажется правильным. или это нормально?

UPDATE 4

Только вернулись к нашей старой версии Dexguard и удалены правила Proguard я добавил.

Крушение больше не происходит, хотя код по-прежнему выглядит точно так же. (промежуточные и полностью скомпилированный код)

Update 5

Switched к Dexguard 7.2 и он пошел безупречно.

+0

Можете ли вы связаться с [email protected] с этой проблемой, включая файлы конфигурации и apk для дальнейшего расследования? –

ответ

1

Оператор switch создаст синтетический внутренний класс с полем массива $SwitchMap$MyEnum, отображающим порядковый номер поля перечисления в целое число, большее 0. Вам нужно убедиться, что этот класс и его поле также сохранены.

+0

Как это сделать или проверить это? – SnyersK

+0

@SnyersK просмотрите созданные файлы классов в вашей * сборке/промежуточных/классах * папках. Это должен быть анонимный внутренний класс. Затем выясните, удалил ли proguard класс или поле. Также было бы интересно узнать, что именно 'Lif'. – tynn

+0

только что обновил мой вопрос с кодом в промежуточных продуктах – SnyersK

 Смежные вопросы

  • Нет связанных вопросов^_^