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:
我想知道:
- Why I don't have to deal with is while using Ant?
- 为什么我不用在使用Ant时处理?
- What is the exact reason for that error to show up? (follows answer to first question)
- 出现这个错误的确切原因是什么?(先回答第一个问题)
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文件,建议将所有的配置都复制过来)。