Desugaring脱糖?


不同的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功能

  • 升级AGP到4.0或者更高
  • compileOptions设置1.8
  • 开启multidex
  • 添加Desugaring依赖
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'

Dex Compiler:D8与R8


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优化包体积


R8在D8的基础上又增加了Proguard的能力,通过开启Shrinking,可以对源码进行优化,以达到减小包体积的目的,具体包括但不限于:

  • 代码删除:通过语法树静态分析技术,发现并剔除未使用的代码,例如没有被实例化的Class等
  • 代码优化:对运行时代码进行优化,包括死代码删除、未使用的参数删除、选择性内联、类合并等。
  • 代码混淆:优化标识符名字,减少代码数量,例如MyAwesomeClass可能被优化成单一字母a

在build.gradle中开启添加一下配置开启Shrinking

android {         ...    buildTypes {             release {                 minifyEnabled false        }    }}

proguard-rule文件中定义优化规则,Android提供了默认的rule文件配置了Android组件类的优化

minifyEnabled trueproguardFiles 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 ");    }}

代码量大大减少,包体积得到控制

更多相关文章

  1. Android(安卓)ActionBar的源代码分析(二)
  2. 安卓手机恶意代码——Samsapo
  3. Android(安卓)之如何优化 UI 渲染(下)
  4. Android中从本地未安装的APK动态加载类和资源
  5. 01、泛型是什么?——《Android打怪升级之旅》
  6. android Button 点击背景与文字颜色变化效果
  7. Android中,在C++层使用TinyXML解析XML文件
  8. 编译android 之后生成的 img 文件介绍
  9. Android(安卓)AOP(二):AspectJ在Android中实现Aop

随机推荐

  1. 流程控制之if判断
  2. 近2万字详解JAVA NIO2文件操作,过瘾!
  3. 半天掌握TypeScript,感觉就像写Java
  4. [jaeger] 二、客户端使用 (Java版本)
  5. 列表类型内置方法
  6. 变量的三个特征
  7. 字符串类型内置方法
  8. 牛气的JavaScript,让雪花算法成为空气
  9. 工作累了,用java写个游戏吧!开源一款游戏引
  10. Python2和3字符编码的区别