切换到Gradle:为什么我要避免自定义视图被混淆?

时间:2021-03-28 14:45:27

I am moving a project from Ant to Gradle, but there's something I just can't figure out.

我正在把一个项目从Ant转移到Gradle,但是有些事情我就是搞不懂。


FACTS

事实

After building a release APK (i.e., obfuscated), I noticed that the app was crashing badly. The error can be summed up by this:

在构建发布APK之后(即我注意到这个应用程序严重地崩溃了。错误可以总结为:

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

A debug (i.e., non obfuscated) APK works just fine, so I guessed it had to do with my ProGuard/DexGuard configuration.

一个调试(即。) APK工作得很好,因此我猜想这与我的ProGuard/DexGuard配置有关。

I tried to keep the class reference by adding the following statement:

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

-keep class com.mypackage.MyCustomView

and, as a result, the release APK works just fine. I then did some research and I tried this more specific ProGuard/DexGuard configuration:

结果,释放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);
}

which also works, and it is class-independent.

这也是可行的,它是独立于阶级的。


QUESTION

问题

I wonder:

我想知道:

  1. Why I don't have to deal with is while using Ant?
  2. 为什么我不用在使用Ant时处理?
  3. What is the exact reason for that error to show up? (follows answer to first question)
  4. 出现这个错误的确切原因是什么?(先回答第一个问题)

ANSWER

回答

The answer from @Blundell was substantially correct. Turns out I was missing one line from the build.gradle configuration:

@Blundell的回答基本上是正确的。原来我在构建中漏掉了一行。gradle配置:

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

It appears that line is actually mandatory, since it serves as a base set of rules for ProGuard/DexGuard. In fact, this is part of the dexguard-release.pro file:

看起来这一行实际上是强制性的,因为它是ProGuard/DexGuard的一组基本规则。事实上,这是dexguard释放的一部分。支持文件:

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

I found the documentation a little bit too vague on this, I hope it can be redacted to clear any ambiguity it might have. All in all, my fault.

我发现文档在这一点上有点太模糊了,我希望它可以被修改以清除它可能存在的任何歧义。总之,是我的错。

1 个解决方案

#1


3  

Most likely Ant was using a different configuration file,

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

Also with Gradle you need to explicitly state you want to also use the Android proguard config file i.e. use multiple rules files like so:

另外,你需要显式地声明你想要使用Android proguard配置文件,即使用多个规则文件,比如:

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

(I remember Ant never used a SDK proguard file and it used to be recommended to copy all the config across).

(我记得Ant从未使用过SDK proguard文件,建议将所有的配置都复制过来)。

#1


3  

Most likely Ant was using a different configuration file,

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

Also with Gradle you need to explicitly state you want to also use the Android proguard config file i.e. use multiple rules files like so:

另外,你需要显式地声明你想要使用Android proguard配置文件,即使用多个规则文件,比如:

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

(I remember Ant never used a SDK proguard file and it used to be recommended to copy all the config across).

(我记得Ant从未使用过SDK proguard文件,建议将所有的配置都复制过来)。