Proguard Rules 配置经验总结
本篇均为个人理解,如果有误请见谅。
代码混淆/minify/shrink
代码混淆的简要工作原理
- 通过tree shake的方式,抛弃不需要的代码,降低dex体积。
- 通过重命名的方式,将类名、变量名、方法名缩短,而不影响运行结果。
混淆规则的常见场景
实体类通过反射序列化/反序列化
开发中经常遇到json与实体类互转的情况,通常会用到Gson,kotlinx.serialization等三方库来实现。其底层是通过反射实现的。反射即通过类名/变量名等的字符串找到对应的类/变量,并通过相应的机制赋值之。
从前述可知,shrink后类名以及类成员名称可能发生改变,所以从json转为实例类的时候就会出现json对应的key在实例中找不到的情况,从实例类转json出现json的key变乱码的情况。
规则也很简单,keep住对应包下的所有类即可。
-keep class com.example.data.** { *; }
如果是用kotlinx.serialization进行实体类的注解,可以用下面规则:
-keep public class * implements java.io.Serializable {*;}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
以 ViewBinding 基类为代表的泛型传递
为了复用的便利,我们经常会定义BaseActivity、BaseFragment等,通过泛型传入binding class,并在基类做初始化。泛型在minify中默认会被抹除,导致运行失败。处理手段是keep住ViewBinding实现类以及继承基类的类。
-keepattributes Signature # 泛型
-keep,allowobfuscation class * implements androidx.viewbinding.ViewBinding { *; }
-keepclassmembers class * implements androidx.viewbinding.ViewBinding { *; }
-keep,allowobfuscation class com.example.base.ui.** { *; }
-keep,allowobfuscation class * extends com.example.base.ui.** { *; }
第三方库的混淆规则
现在先进一点的三方库会自带规则,如果没有的话需要看对应的README去添加上,常见于一些商业性质的库。
问题排查
很难避免开启minify后App运行异常甚至闪退的情况,这时候需要认真查看crash log去定位,必要时需了解一些smali知识。往往排查问题所在才是最耗时的。