Android Studio 3.0+ 新Dex编译器D8 Desugar R8
原文链接
https://blog.csdn.net/jamin0107/article/details/81123154
〇.序
将.class自己码转化为.dex字节码作为Apk打包的关键步骤,Google打算在Android 3.0中引入D8作为原先Dex的升级版,以及R8作为原本Proguard 压缩与优化(minification、shrinking、optimization)部分的替代品。升级Dex编译器将直接影响构建时间,.dex文件大小,运行时性能。
一.D8
1.1 D8 的功能是把java字节码转化成dex代码,D8作为DX的一个替换方案。
谷歌通过自己的 基准测试项目测出,编译时间缩短了20%,而且.dex文件更小,虽然只有几个百分比。D8编译的.dex文件将拥有相同或者是更好的运行时性能。
Java 8支持相关
Android Studio 3.0 及以上版本支持所有 Java 7 语言功能,以及部分 Java 8 语言功能(具体因平台版本而异)。
注:在开发 Android 应用时,可以选择使用 Java 8 语言功能。 您可以将项目的源代码和目标代码兼容性值保留为 Java 7,但仍须使用 JDK 8 进行编译。
Android Studio 为使用部分 Java 8 语言功能及利用这些功能的第三方库提供内置支持。 如图 1 所示,默认工具链对 javac 编译器的输出执行字节码转换(称为 desugar),从而实现新语言功能。 Jack 不再受支持,您需要首先停用 Jack 才能使用默认工具链内置的 Java 8 支持。
目前Java 8语言支持的处理是在javac之后,与字节码处理工具处理之前。在接下来的几个月,这个步骤将会被移动到pipeline的后一个阶段,作为D8的一部分。
其带来的影响:
减少这块的编译时间
可以优化更多代码
这么一来,所有字节码处理工具就必须要支持Java8的字节码格式了。
1.2 D8的使用
已经在Android Studio 3.0 Beta release中引入
Android Studio 3.0
需要主动在gradle.properties文件中新增:android.enableD8=true
Android Studio 3.1或之后的版本
在3.1或之后的版本D8将会被作为默认的Dex编译器。如果遇到问题,你可以通过修改gradle.properties文件里的一个属性恢复到DX android.enableD8=false
除了其他好处外,使用D8还有一个好处,就是支持 脱糖,让Java 8才提供的特性(如lambdas)可以转换成Java 7特性。把脱糖步骤集成进D8影响了所有读或写.class字节码的开发工具,因为它会使用Java 8格式。你可以在gradle文件中设置一个属性,恢复到以前的行为,让脱糖发生在Java编译之后,.class字节码仍遵循Java 7格式:android.enableD8.desugaring = false
1.3脱糖(Desugar)
当我们选择JDK8以上版本时,有时候会使用lambda表达式,在设置android.enableD8.desugaring = false的时候。编译链会对lambda表达式进行一次脱糖处理。请看下面的例子。
1.3.1 纯函数脱糖
源代码很简单:
一个简单的Activity,设置ClickListener一种是Java7以下的传统写法,一种是Java8的Lambda表达式写法
public class MainActivity extends Activity {@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = findViewById(R.id.click);//lambda写法tv.setOnClickListener(view -> {Log.d("MainActivity", "MainActivity");});//普通写法tv.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View view) {Log.d("MainActivity", "MainActivity");}});}
}
编译后的Class文件如下:
路径为
app/build/intermediates/transforms/desugar/release(buildType)/0/com.jamin.d8desugar(packageName)/
public class MainActivity extends Activity {public MainActivity() {} protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(2130968576);TextView tv = (TextView)this.findViewById(2130903040);//直接使用Lambda表达式脱糖后的静态引用tv.setOnClickListener(MainActivity$$Lambda$0.$instance);tv.setOnClickListener(new OnClickListener() {public void onClick(View view) {Log.d("MainActivity", "MainActivity");}});}
}
//Class文件中生成静态引用
final class MainActivity$$Lambda$0 implements OnClickListener {static final OnClickListener $instance = new MainActivity$$Lambda$0();private MainActivity$$Lambda$0() {}public void onClick(View var1) {MainActivity.lambda$onCreate$0$MainActivity(var1);}
}
实际上非D8脱糖,为了保证JAVA7及以下的兼容性。是将lambda表达式的在javac编译class的时候就已经将lambda表达式转化成更高兼容度的低版本代码。好处是在编译链中,有时候会使用一些java7的工具。他们对于java8的语法糖是无法识别的。
1.3.2 非纯函数脱糖
好,我们简单改写一下源文件
public class MainActivity extends Activity {String abc = "abc"; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = findViewById(R.id.click);tv.setOnClickListener(view -> {Log.d("MainActivity", "MainActivity" + abc);});tv.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View view) {Log.d("MainActivity", "MainActivity" + abc);}});}
}
生成的class文件如下:
public class MainActivity extends Activity {String abc = "abc";public MainActivity() {} protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(2130968576);TextView tv = (TextView)this.findViewById(2130903040);//注意this传递过去了。类似于内部类的写法tv.setOnClickListener(new MainActivity$$Lambda$0(this));tv.setOnClickListener(new OnClickListener() {public void onClick(View view) {Log.d("MainActivity", "MainActivity" + MainActivity.this.abc);}});}
}
// $FF: synthetic class
final class MainActivity$$Lambda$0 implements OnClickListener {private final MainActivity arg$1;MainActivity$$Lambda$0(MainActivity var1) {this.arg$1 = var1;}public void onClick(View var1) {this.arg$1.lambda$onCreate$0$MainActivity(var1);}
}
此时生成的class文件就不是纯函数了。所以会不会内存泄漏?
1.3.3 D8脱糖
在设置android.enableD8.desugaring = true的时候(高版本,比如AGP的版本是com.android.tools.build:gradle:3.3.0-alpha03时,默认是D8脱糖),D8脱糖就不会在transforms目录下生成desugar目录。反编译transforms/dexBuilder/中的jar包。可以看到在jar包中,已经是脱糖后的结果了。大家可以看下图。也是把lambda表达式生成一个静态对象。
当然D8脱糖,要求编译链中所有工具都支持java8,不然不认识class文件中的部分语法糖。D8脱糖的好处是什么呢。官方的话说就是可以提高编译速度。
二.R8
R8作为原本Proguard 压缩与优化(minification、shrinking、optimization)部分的替代品,依然使用与Proguard一样的keep规则。
目前R8已经开源: r8/r8,其包含了D8与R8。
目前R8还没有整合进Android Gradle plugin,不过由于其已经开源,根据文档可以很快的在python环境下运行起来:
确保本地已经安装了python 2.7或更高版本(macOS Sierra自带python 2.7)。
由于R8项目使用chromium项目提供的depot_tools管理依赖,因此先安装depot_tools
Clone R8项目:git clone https://r8.googlesource.com/r8 && cd r8
下载一个Gradle版去编译,并且声称两个jar文件: build/libs/d8.jar与build/libs/r8.jar: python tools/gradle.py d8 r8
根据r8文档进行使用即可
BREAKING NEWS:新版AndroidStudio可以体验一下。
New code shrinker
R8 is a new tool for code shrinking and obfuscation that replaces ProGuard. You can start using the preview version of R8 by including the following in your project’s gradle.properties file:
android.enableR8 = true
官方文档: New code shrinker
参考资料
- Android Studio switching to D8 dexer
- Next-generation Dex Compiler Now in Preview
- 官方文档 : 使用 Java 8 语言功能
Android Studio 3.0+ 新Dex编译器D8 Desugar R8相关推荐
- Android Studio 4.0 新功能与优化
1.前言 Android Studio又更新了,每次重大更新都给我们的生产力提升了一个台阶,当然也会带来神奇的bug,墙裂提醒各位小伙伴升级请慎重!!! [真香警告]Android Studio下载链 ...
- android studio 3.0新功能介绍
谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快.(英语一般,有些翻译不太好) 下载地址 https://developer.android.g ...
- 神经网络API、Kotlin支持,那些你必须了解的Android 8.1预览版和Android Studio 3.0新特性
曾仅用 55 秒发布会的 Android 8.0 Oreo 在时隔两个月后,Google 于今天在其官方网站上正式发布了 Android 8.1 首个开发者预览版,此次升级涵盖了针对多个功能的提升优化 ...
- Android studio 4.2新特性及升级异常
Android studio 版本及特性系列目录 Android 12 终于来了,你准备好了吗? Android studio 4.2新特性 Android studio 4.1新特性 Android ...
- android 编译器有问题,Android Studio 3.0 Beta 2发布:解决编译器bug
5月18日,IT之家曾经报道,谷歌发布了Android Studio 3.0的测试版,新增了对Kotlin语言的支持,而日前,谷歌发布了Android Studio 3.0的Beta 2版本. 此版本 ...
- android 模拟器 2.0,Android Studio 2.0 之 新的模拟器
上个星期,Android Studio 2.0 的稳定版终于发布了,于是我马上兴冲冲的升级了. Android Studio 2.0 最突出的主新特性有两个: Instant Run -- 即时运行, ...
- visual studio 最新稳定版本_速来围观!Android Studio 4.0 稳定版发布了
作者:恋猫de小郭 Android Studio 4.0(2020年5月) 更新啦!此版本包含了各种新功能和改进,还有一些废弃配置. 重要提示:更新后,需要重新启动 Android Studio 才能 ...
- Android Studio 3.0 正式版本 发行说明 (翻译)
前言 as终于发正式版了.赶快来看看有什么新的功能.本文采用翻译器翻译. Android Studio是为Android开发的官方IDE,包含构建Android应用程序所需的一切. 1.要获取最新版本 ...
- Android Studio 4.0 稳定版发布了
Android Studio 4.0(2020年5月) 更新啦,此版本包含了各种新功能和改进,还有一些废弃配置. 重要提示:更新后,需要重新启动 Android Studio 才能应用从早期版本的 I ...
最新文章
- 梯度算法求步长的公式_LM(Levenberg-Marquarelt)算法
- 自动驾驶车辆何时实现?近期不会实现的五大原因
- 【POJ1144】Network
- VM:Vmware简介、安装、使用方法详细攻略
- 云信小课堂|如何实现音视频通话
- 解决Eclipse代码分析插件SonarLint在Console输出乱码问题
- 机器学习基础-神经网络-10
- Android 中的 Context
- 女朋友心血来潮帮我清洗电脑
- 斜杠青年Ruff:区块链只是分内事
- es为mysql创建索引_ES(ElasticSearch) 索引创建
- cat >> ipconf << EOF > EOF是什么意思
- Java课程报告实验总结,java实验报告总结 [Java课程设计实验报告]
- 网络安全:漏洞测试主要平台 BackTrack4+Metasploit+ruby
- cad2019菜单栏怎么调出来_AutoCAD2019工具栏怎么调出来 工具栏没了找不到解决方法...
- python实现屏幕截图_Python实现计算机屏幕任意区域截图
- linux 切换 amd 显卡,ubuntu 14.10 (64位)下载amd显卡,实现双显卡切换
- VS之Excel文件操作
- STM32F407 STM32F407 LWIP速度优化测试速度可以达到1万kb每秒 相当于80兆的网络速度
- parameterType和@Param注解用法
热门文章
- 武汉大学计算机音乐,名家论坛丨预告:聆听音乐
- 记录h5文件数据转为npy和csv格式类型的方法
- 高含金量国际计算机编程竞赛
- 在安卓项目中使用gifsicle编辑GIF动图-Android NDK 编译 gifsicle 为可执行文件记录
- 【iOS开发】—— SDWebImage源码学习(未完)
- 微信公众号平台服务器配置请求url超时,绑定微信公众平台提示请求URL超时怎么办...
- RAID 独立冗余磁盘阵列详解(RAID 0、RAID 1、RAID 5、RAID 10)
- ACRush 楼天城 回忆录
- 连连看修改(golang)
- 来,我们谈谈怎么选购一台笔记本