Gradle 插件升级注意事项

一些在升级 Gradle 插件时可能遇到的问题。

3.6.0+

测试代码:

1
2
3
4
5
6
7
8
public class User {

private String name;

public String getName() {
return name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void test() throws Exception {
final String name = "admin";
Assert.assertEquals(name, createUserWithName(name).getName());
}

private User createUserWithName(String name) throws IllegalAccessException {
User user = new User();
Field[] fields = user.getClass().getDeclaredFields();
if (fields.length > 0) {
Field field = fields[0];
field.setAccessible(true);
field.set(user, name);
}
return user;
}

升级之前的环境:

1
2
3
4
5
6
7
8
9
10
dependencies {
classpath "com.android.tools.build:gradle:3.5.4"
}

buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

这时运行上面的测试代码是没有问题的,接下来升级一下 Gradle 插件版本,其它环境不变:

1
2
3
dependencies {
classpath "com.android.tools.build:gradle:3.6.0"
}

运行结果:

1
2
3
4
5
6
7
com.android.example E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.example, PID: 19544
java.lang.AssertionError: expected:<admin> but was:<null>
at c.a.a.a(Assert.java:89)
at c.a.a.b(Assert.java:835)
at c.a.a.a(Assert.java:120)
at c.a.a.a(Assert.java:146)

为什么运行结果是 null ?,在 Android Studio 中打开 app/build/outputs/apk/debug/app-debug.apk,看一下 dex 中混淆后的 User 类反编译出来的 smali:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.class public Lcom/android/example/a;
.super Ljava/lang/Object;
.source "User.java"


# direct methods
.method public constructor <init>()V
.registers 1

.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V

return-void
.end method


# virtual methods
.method public a()Ljava/lang/String;
.registers 2

.line 8
const/4 v0, 0x0

return-object v0
.end method

可以看到 name 这个属性直接被优化移除了,getName 虽然还在,但是直接返回了 null

解决办法:

  • 添加混淆规则

    1
    -keepclassmembers, allowobfuscation class com.android.example.User {*;}
  • 回退 Gradle 插件版本

    1
    2
    3
    dependencies {
    classpath "com.android.tools.build:gradle:3.5.4"
    }

参考