Skip to content

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知识。往往排查问题所在才是最耗时的。

上次更新于: