109
社区成员




这个作业属于哪个课程 | https://bbs.csdn.net/forums/2401_CS_SE_FZU |
---|---|
这个作业要求在哪里 | https://bbs.csdn.net/topics/619470310 |
这个作业的目标 | 个人技术总结 |
其他参考文献 | 无 |
代码混淆具有三大主要好处,一是降低apk包体体积;二是降低smali可读性,缓解反编译带来的安全风险;三是降低dex数目,加快运行速度。
代码混淆的简要工作原理是:
本次新苗同学App开发后期优化过程中,观测到App包体较大,对于成本控制和用户体验等方面都有不良影响。因此,决定启用代码混淆解决此问题。
混淆规则(Proguard Rules)需要结合项目情况手工配置,没有统一解,异常情况需要自行分析日志解决。
在app级的build.gradle.kts
中,修改release类型的配置,开启minify并指定规则文件为同级目录下proguard-rules.pro
文件。
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
)
}
}
在左侧栏Build Variants
中,切换Active Build Variant
为release,执行Gradle Build任务并进行安装,测试是否出现闪退、数据不正常的情况。
对症下药,配置对应规则,重新进行编译测试。
经过测试,总结出几种常用规则如下:
开发中经常遇到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 *;
}
为了复用的便利,我们经常会定义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去添加上,常见于一些商业性质的库。
在排查 ViewBinding 混淆问题时,发现部分binding类在Signature中变为了Object类,导致运行失败。
用Android Studio打开apk,加载mapping文件,查看到混淆前后的映射:
查看编译后指定类的字节码:
在proguard.rules
中配置输出被r8优化掉的类情况:
-printusage r8usage.txt
排查发现,r8将部分ViewBinding类移除了。查看对应规则,发现ViewBinding类的规则头部写成了
-keep,allowobfuscation,allowshrinking
即意味着允许shrink掉r8不使用的类,而通过反射实现的ViewBinding调用导致了误判。按如下修改得到解决。
-keep,allowobfuscation
很难避免开启minify后App运行异常甚至闪退的情况,这时候需要认真查看crash log去定位,必要时需了解一些smali知识。往往排查问题所在才是最耗时的。
《Proguard Rules 配置经验总结》,作者徐煜晖:https://www.klxiaoniu.top/android/proguard.html