前言
当 library 启用 proguard 混淆打包成 aar 供第三方调用时,方法的参数名会被删除掉,这样用户就不知道参数的含义,然而作为一个库应该保留参数名。
过程
测试代码:
接下来就是打包 aar 了,这里省略流程。用 jadx 查看一下编译出来的 aar 文件,方法的参数名很显然不是我们自己写的名字,这就是被编译器抹掉了。像这种不存在参数信息的 aar 放到 Android Studio 里用会显示 p0 p1 p2 ...
于是可以在 proguard-rules.pro 中添加:
-keepparameternames
-keepattributes MethodParameters
编译后再用 jadx 打开看一下,结果和原来的还是一样,猜测参数名应该是在混淆前抹掉的。从 apk 的编译流程可知,混淆前的流程就是 javac 编译源码,后来查阅相关资料才发现 javac 默认不保留这些调试信息,方法参数名也包括在内。
幸运的是,javac 提供了参数用于保留这些调试信息:
所以我们应该在 gradle 里给 javac 添加编译参数:
Groovy:
android{
...
tasks.withType(JavaCompile) {
options.compilerArgs += ["-g", "-parameters"]
}
...
}
Kotlin:
android{
...
tasks.withType<JavaCompile> {
options.compilerArgs.addAll(listOf("-g", "-parameters"))
}
...
}
再次编译:
可以看到参数被保留了。但这只是针对 java 源文件,现在的趋势都是 kotlin ,测试了一下 kotlin 编译后的参数名还是被删掉了,偶然发现 kotlinOptions ,尝试配置:
// app/build.gradle.kts
kotlinOptions {
javaParameters = true
}
编译后 kotlin 的参数名信息也被保留了~
撒花
最后要注意的是,当开启 proguard 后,只有被 keep 的类才会保留参数名。也就是说,就算你按照上述步骤配置了保留参数,proguard-rules.pro 里不配置 keep class 的话参数名依然会被抹掉。