赞
踩
不同的Android版本支持的Jvm版本不同,当使用当前Abndroid版本不支持的高版本jdk语法时,需要在编译期转换为其支持的低版本jdk语法,这个过程成为desugaring脱糖。
我们分别在Android R (API 30) 和 Android M (API 23)上分别调用Java8新引入的时间API
tv_month.text = LocalDate.now().month.name
AndroidR可以正常运行,但是AndroidM出现了NoClassDefFoundError
为解决此问题,我们需要开启Desuguring功能
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
Desuguring是如何实现的呢?是借助dex编译器D8与R8实现的。
早期,Android从源码到字节码再到dex的编译过程如下,中间使用Proguard进行字节码优化:
由于过程复杂,2015年左右Google退出了Jack&Jill编译器,减少了中间环节:
过与简化的编译过程,无法在过程中加入更多优化,因此Google在2017年废弃了Jack&Jill,重新回到了之前的编译流程,只是重写了最后一步dex编译器,称之为D8。一个完整的编译流程需要Proguard和D8同时参与其中
R8的出现整合了Proguard和DB,减少了一个编译步骤,同时保留了字节码优化的能力。
Desugaring的工作原理是 R8/D8在字节码编译成Dex文件时,通过三方库的引入支持了原本不支持的高版本JDK语法,并一同打进dex,使之可以正常工作
R8在D8的基础上又增加了Proguard的能力,通过开启Shrinking,可以对源码进行优化,以达到减小包体积的目的,具体包括但不限于:
在build.gradle中开启添加一下配置开启Shrinking
android {
...
buildTypes {
release {
minifyEnabled false
}
}
}
proguard-rule
文件中定义优化规则,Android提供了默认的rule文件配置了Android组件类的优化
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
例如针对如下代码
class JavaHelloWorld { //unreachable code private void iAmUnused() { System.out.println("I am of no use "); } //reachable code private static void reachableExample() { System.out.println("Hello, World "); } //main function public static void main(String[] args) { reachableExample(); } }
R8会进行如下优化
iAmUnused
作为不可达代码进行删除reachableExample
被内联到main中优化后的代码变为
class JavaHelloWorld {
//main function
public static void main(String[] args) {
System.out.println("Hello, World ");
}
}
代码量大大减少,包体积得到控制
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。