当我们编译Android Release模式时,一般都会出发Proguard文件,进行混淆压缩代码,首先在java编译器的帮助下将java代码编译成class文件,之后proguard会优化class字节码,之后在dalvik虚拟机的帮助下,编译成dex,即
.java — javac →.class (进行脱糖)— Proguard → 优化后的.class — Dex → .dex
备注:由于不同Android版本支持的jvm版本不同,当前的Android版本不支持高版本的jdk语法时,就会在编译期转换为低版本的jdk,这个过程就叫脱糖
脱糖算是java8的一个新特性,但是代价就是更长的build时间
后来在2015年左右,Android推出了Jack&Jill编译器,减少了中间环节:
.java— Jack & Jill → .dex
但中间环节过于简化,不够灵活,在2017年左右,又推出了D8,只进行最后一步优化:
.java — javac →.class — Proguard → 优化后的.class — D8 → .dex
D8进程负责优化dex代码,现在Android同时支持Kotlin和Java,需要在proguard文件中保留class
之后又在AndroidStudio 3.3的版本开始加入R8,用来代替proguard作为默认压缩工具,达到更快更小的目的
3.3版本需要设置android.enableR8=true
3.4版本默认开启,在表面上,proguard和R8很相似,配置相同,容易切换,细节上看,R8更擅长内联对象,避免分配过多对象
R8对kotlin更加友好,kotlin虽然能写出更漂亮的代码,但是编译时,一般会产生比java更多的指令,但是R8对此进行了专门的优化,R8工作之后,项目最终的结果,还是使用kotlin的压缩效果会更好一些
在项目中设置minifyEnabled true,就会开启Shrinking,通过语法树静态分析,剔除未被调用的代码,同时对运行时代码进行优化,包括选择性内联、类合并等,从而达到减少代码的目的