包体积优化 ReDex 分析
https://github.com/facebook/redex
通用字节码优化
ConstantPropagationPass
对方法进行数据流分析,可能会产生一些死代码,这也为后续的死代码删除创造了条件。
1 int x = 14;
2 int y = 7 - x / 2;
3 return y * (28 / x + 2);
4 —>
5 int x = 14;
6 int y = 7 - 14 / 2;
7 return (7 - 14 / 2) * (28 / 14 + 2);
上面的例子经过 常量折叠 + 常量传播优化后就会简化为
1 int x = 14;
2 int y = 0;
3 return 0;AnnoKillPass
该 Pass 是用来移除无用注解的RenameClassesPass
该 Pass 通过缩减类名的字符串长度来减小包体积
比如把类名从La/b/c/d/e;改为LX/a;,可以类名字符串的长度,从而达到包大小缩减的目的。
实际上 Proguard 本身已经提供类似的功能: -repackageclasses ‘X’,但是-repackageclasses ‘X’的处理会影响 ReDex 的 InterDexPass 的算法逻辑(InterDexPass 可以参考下文),导致收益缩减,收益测试:
Proguard -repackageclasses ‘X’ 收益: 600K+
Redex InterDexPass 收益: 400K+
同时应用 Proguard -repackageclasses ‘X’ 和 Redex InterDexPass 收益: 40K+
- StringBuilderOutlinerPass
……
DEX 格式优化
- InterDexPass
该 Pass 是针对跨 DEX 引用的优化,该优化对单 DEX 的应用是无效的。
进行类重排后,可以减少跨dex引用
具体的优化过程是:
- 收集每个类涉及的所有引用,按照引用数量和类型计算出类的权重
- 根据权重计算出每个类的优先级
- 根据优先级选取一个类放入 DEX 中,然后调整剩余类的优先级,重复此步骤直到所有类都被处理
ReBindRefsPass
该 Pass 是针对方法引用的优化,其原理同 InterDexPass。
……KotlinDataClassPass
对 data class 的生成代码进行精简RegAllocPass
RegAllocPass 就是通过重新分配寄存器来提升压缩率的
……
Redex使用
https://juejin.cn/post/6844904103131234311#heading-48
https://fbredex.com/docs/installation
–sign:对生成的apk进行签名。
-s:配置应用的签名文件。
-a: 配置应用签名的 key_alias。
-p:配置应用签名的 key_password。
-c:指定 redex 进行 Dex 处理时需要依据的 CONFIG 配置文件。
-o:指定生成 APK 的全路径。
python3 redex.py –android-sdk-path /Users/stew/Library/Android/sdk –sign -s /Users/stew/kotlinboxsign/kotlinbox -a kotlinbox -p kotlinbox -c /Users/stew/Desktop/STEW/redex/config/default.config -P /Users/stew/Desktop/STEW/KotlinBox/app/proguard-rules.pro -o /Users/stew/Desktop/STEW/KotlinBox/app/release/app-release-redex.apk /Users/stew/Desktop/STEW/KotlinBox/app/release/app-release.apk
坑:
1.需要配置c++,升级xcode就行,mac需要升级系统
2.app内需要配置混淆规则,不能空着
App 的 Dex 数量越多,那么优化的效果就会越大
参考文章:
https://juejin.cn/post/7104228637594877965
https://juejin.cn/post/6844904103131234311#heading-48
https://fbredex.com/docs/installation
https://github.com/facebook/redex