10

Я перемещаю проект от Ant до Gradle, но есть кое-что, что я просто не могу понять.Переключение в Gradle: почему я должен запрещать запутывание пользовательских представлений?


ДАННЫЕ

После построения выпуска APK (т.е. затемненный), я заметил, что приложение было сбой плохо. Ошибка может быть суммированы следующим образом:

java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet] 

отладки (то есть, не затемненный) APK работает просто отлично, так что я предположил, что это было связано с моей ProGuard/DexGuard конфигурации.

Я пытался сохранить ссылку на класс, добавив следующее утверждение:

-keep class com.mypackage.MyCustomView 

и, как следствие, релиз APK работает просто отлично. Затем я сделал некоторые исследования, и я попытался это более конкретная конфигурация ProGuard/DexGuard:

-keep public class * extends android.view.View { 
    public <init>(android.content.Context); 
    public <init>(android.content.Context, android.util.AttributeSet); 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
    public void set*(...); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
} 

-keepclasseswithmembers class * { 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

, который также работает, и это класса независимого.


ВОПРОС

Интересно:

  1. Почему я не приходится иметь дело с в то время как с помощью Ant?
  2. Какова конкретная причина появления этой ошибки? (Следующим образом ответить на первый вопрос)

ОТВЕТ

Ответ от @Blundell был по существу правильно. Оказывается, я пропускал одну линию от конфигурации build.gradle:

android { 
    ... 
    buildTypes { 
    debug { 
     ... 
    } 
    release { 
     proguardFile getDefaultDexGuardFile('dexguard-release.pro') # <----- this line 
     proguardFile 'dexguard-project.txt' 
    } 
    } 
} 

Вероятно, что линия на самом деле является обязательным, так как он служит в качестве базового набора правил для ProGuard/DexGuard. На самом деле, это часть файла dexguard-release.pro:

-keepclassmembers !abstract class !com.google.ads.** extends android.view.View { 
    public <init>(android.content.Context); 
    public <init>(android.content.Context, android.util.AttributeSet); 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
    public void set*(...); 
} 

-keepclassmembers !abstract class * { 
    public <init>(android.content.Context, android.util.AttributeSet); 
    public <init>(android.content.Context, android.util.AttributeSet, int); 
} 

-keepclassmembers class * extends android.content.Context { 
    public void *(android.view.View); 
} 

Я нашел документацию немного слишком расплывчатое на это, я надеюсь, что это может быть отредактирован, чтобы очистить любую двусмысленность может иметь. В общем, моя вина.

+0

как/где вы создаете свой собственный вид? – pskink

+0

Конструкторы должны храниться, потому что 'LayoutInflater' использует их, но это не может быть выведено из статического анализа только источника. Я предполагаю, что ваш реальный вопрос - почему конфигурация по умолчанию ProGuard/DexGuard, которая раньше была частью SDK, не использовалась? Я предполагаю, что это связано с недавними изменениями в плагине Gradle, а также с переименованием 'runProguard' и другими подобными вещами. Если вы используете ProGuard из SDK, обратитесь в группу adt-dev Google. Если вы используете DexGuard, проверьте портал загрузки, было несколько последних обновлений в быстрой последовательности. – Barend

+0

@Barend Я не уверен, почему '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' должен использоваться. Мне интересно, почему в Ant и Gradle существует другое поведение, поскольку оба используют одну и ту же версию DexGuard, и оба используют один и тот же файл конфигурации. – Sebastiano

ответ

3

Скорее всего Ant использует другой файл конфигурации,

Также с Gradle вам нужно явно указать, вы хотите использовать конфигурационный файл Android Proguard т.е.использовать несколько файлов правил, как так:

proguardFile getDefaultProguardFile('proguard-android.txt') 
    proguardFile 'your/sepcific/folder/proguard.cfg' 

(я помню Ant никогда не использовал файл Proguard SDK и раньше рекомендуется скопировать все конфигурации в поперечнике).

+0

Нет, я (по-прежнему) использую тот же файл конфигурации. Единственное отличие теперь состоит в сохранении пользовательских представлений. Кроме того, я дважды проверял свой build.gradle, он правильно указывает на мой файл конфигурации (в противном случае другие вещи перестанут работать). – Sebastiano

+0

Я обновил OP с вашим ответом и причиной такого поведения. – Sebastiano

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