切换到Gradle:为什么我必须保持自定义视图不被混淆?

Seb*_*ano 10 android proguard android-custom-view android-gradle-plugin dexguard

我正在将一个项目从Ant转移到Gradle,但有些东西我无法理解.


FACTS

在构建发布APK(即混淆)后,我注意到应用程序崩溃严重.错误可以通过以下方式总结:

java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
Run Code Online (Sandbox Code Playgroud)

调试(即非混淆)APK工作正常,所以我猜测它与我的ProGuard/DexGuard配置有关.

我试图通过添加以下语句来保持类引用:

-keep class com.mypackage.MyCustomView
Run Code Online (Sandbox Code Playgroud)

因此,发布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);
}
Run Code Online (Sandbox Code Playgroud)

它也有效,而且与课程无关.


我想知道:

  1. 为什么我不需要处理是在使用Ant时?
  2. 出现错误的确切原因是什么?(按照第一个问题回答)

回答

@Blundell的答案基本上是正确的.结果我错过了build.gradle配置中的一行:

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

看来该行实际上是强制性的,因为它是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);
}
Run Code Online (Sandbox Code Playgroud)

我发现文档对此有点过于模糊,我希望可以通过编辑来清除它可能带来的任何歧义.总而言之,我的错.

Blu*_*ell 4

Ant 很可能使用不同的配置文件,

另外,对于 Gradle,您需要明确声明您还想使用 Android proguard 配置文件,即使用多个规则文件,如下所示:

    proguardFile getDefaultProguardFile('proguard-android.txt')
    proguardFile 'your/sepcific/folder/proguard.cfg'
Run Code Online (Sandbox Code Playgroud)

(我记得 Ant 从未使用过 SDK proguard 文件,并且过去建议复制所有配置)。