写点什么

Android D8 编译器 和 R8 工具,android 零基础开发

用户头像
Android架构
关注
发布于: 2021 年 11 月 05 日

1.3 Android Studio 3.4 版本 D8 R8 变更

Android Studio 3.4 版本中,R8desugaringshrinkingobfuscatingoptimizingdexing 都合并到一步进行执行。在 Android Studio 3.4 以前的版本编译流程如下:



合并之后编译流程如下:



注意,如果我们在 build.gradle 中配置了 useProguard = false 则不管是否开启 R8 编译都会使用 R8 进行压缩代码。

2. 脱糖

Android Studio 为使用部分 Java 8 语言功能及利用这些功能的第三方库提供内置支持。默认工具链对 javac 编译器的输出执行字节码转换(称为 desugar),从而实现新语言功能。


脱糖即在编译阶段将在语法层面一些底层字节码不支持的特性转换为基础的字节码结构,(比如 List 上的泛型脱糖后在字节码层面实际为 Object); Android 工具链对 Java8 语法特性脱糖的过程可谓丰富多彩,当然他们的最终目的是一致的:使新的语法可以在所有的设备上运行。


经过上面 D8R8 的了解,D8 已经支持脱糖,让 Java 8 提供的特性(如 lambdas)可以转换成 Java 7 特性。把脱糖步骤集成进 D8 影响了所有读或写 .class 字节码的开发工具,因为它会使用 Java 8 格式。可以在 gradle.properties 中禁用脱糖。


android.enableIncrementalDesugaring=false.android.enableDesugar=false

2.1 Lambda 表达式

Java 8 中一个重大变更是引入 Lambda 表达式。


public class Lambda {public static void main(String[] args) {logDebug(msg-> System.out.println(msg), "HelloWorld");}


static void logDebug(Logger logger, String msg) {logger.log(msg);}


@FunctionalInterfaceinterface Logger {void log(String msg);}}


通过 javac 指令将上面的 Lambda.java 转换为字节码。


$javac Lambda.java


接下来通过 javap -v 指令查看字节码的详细内容:


dengshiweideMacBook-Pro:Desktop dengshiwei javap -v Lambda.classClassfile /Users/dengshiwei/Desktop/Lambda.classLast modified 2019-5-12; size 1120 bytesMD5 checksum 67301305720e60d4ef1ff286769768e6Compiled from "Lambda.java"public class Lambdaminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPERConstant pool:#1 = Methodref #9.#25 // java/lang/Object."<init>":()V#2 = InvokeDynamic #0:#30 // #0:log:()LLambdaLogger;#3 = String #31 // HelloWorld#4 = Methodref #8.#32 // Lambda.logDebug:(LLambdaLogger;Ljava/lang/String;)V#5 = InterfaceMethodref #10.#33 // LambdaLogger.log:(Ljava/lang/String;)V#6 = Fieldref #34.#35 // java/lang/System.out:Ljava/io/PrintStream;#7 = Methodref #36.#37 // java/io/PrintStream.println:(Ljava/lang/String;)V#8 = Class #38 // Lambda#9 = Class #39 // java/lang/Object#10 = Class #40 // LambdaLogger#11 = Utf8 Logger#12 = Utf8 InnerClasses#13 = Utf8 <init>#14 = Utf8 ()V#15 = Utf8 Code#16 = Utf8 LineNumberTable#17 = Utf8 main#18 = Utf8 ([Ljava/lang/String;)V#19 = Utf8 logDebug#20 = Utf8 (LLambdaLogger;Ljava/lang/String;)V#21 = Utf8 lambda0#22 = Utf8 (Ljava/lang/String;)V#23 = Utf8 SourceFile#24 = Utf8 Lambda.java#25 = NameAndType #13:#14 // "<init>":()V#26 = Utf8 BootstrapMethods#27 = MethodHandle #6:#41 // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandlesLookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;#28 = MethodType #22 // (Ljava/lang/String;)V#29 = MethodHandle #6:#42 // invokestatic Lambda.lambdamain0:(Ljava/lang/String;)V#30 = NameAndType #43:#44 // log:()LLambdaLogger;#31 = Utf8


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


 HelloWorld
复制代码


#32 = NameAndType #19:#20 // logDebug:(LLambdaLogger;Ljava/lang/String;)V#33 = NameAndType #43:#22 // log:(Ljava/lang/String;)V#34 = Class #45 // java/lang/System#35 = NameAndType #46:#47 // out:Ljava/io/PrintStream;#36 = Class #48 // java/io/PrintStream#37 = NameAndType #49:#22 // println:(Ljava/lang/String;)V#38 = Utf8 Lambda#39 = Utf8 java/lang/Object#40 = Utf8 LambdaLogger#41 = Methodref #50.#51 // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandlesLookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;#42 = Methodref #8.#52 // Lambda.lambdamain0:(Ljava/lang/String;)V#43 = Utf8 log#44 = Utf8 ()LLambdaLogger;#45 = Utf8 java/lang/System#46 = Utf8 out#47 = Utf8 Ljava/io/PrintStream;#48 = Utf8 java/io/PrintStream#49 = Utf8 println#50 = Class #53 // java/lang/invoke/LambdaMetafactory#51 = NameAndType #54:#57 // metafactory:(Ljava/lang/invoke/MethodHandlesLookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;#52 = NameAndType #21:#22 // lambdamain0:(Ljava/lang/String;)V#53 = Utf8 java/lang/invoke/LambdaMetafactory#54 = Utf8 metafactory#55 = Class #59 // java/lang/invoke/MethodHandlesLookup#56 = Utf8 Lookup#57 = Utf8 (Ljava/lang/invoke/MethodHandlesLookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;#58 = Class #60 // java/lang/invoke/MethodHandles#59 = Utf8 java/lang/invoke/MethodHandlesLookup#60 = Utf8 java/lang/invoke/MethodHandles{public Lambda();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0


public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: invokedynamic #2, 0 // InvokeDynamic #0:log:()LLambdaLogger;5: ldc #3 // String HelloWorld7: invokestatic #4 // Method logDebug:(LLambdaLogger;Ljava/lang/String;)V10: returnLineNumberTable:line 3: 0line 4: 10


static void logDebug(LambdaLogger;Ljava/lang/String;)Vflags: ACC_STATICCode:stack=2, locals=2, args_size=20: aload_01: aload_12: invokeinterface #5, 2 // InterfaceMethod LambdaLogger.log:(Ljava/lang/String;)V7: returnLineNumberTable:line 7: 0line 8: 7}SourceFile: "Lambda.java"InnerClasses:static #11= #10 of #8; //Logger=class LambdaLogger of class Lambdapublic static final #56= #55 of #58; //Lookup=class java/lang/invoke/MethodHandlesLookup of class java/lang/invoke/MethodHandlesBootstrapMethods:0: #27 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandlesLookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android D8 编译器 和 R8 工具,android零基础开发