文末
那么对于想坚持程序员这行的真的就一点希望都没有吗?
其实不然,在互联网的大浪淘沙之下,留下的永远是最优秀的,我们考虑的不是哪个行业差哪个行业难,就逃避掉这些,无论哪个行业,都会有他的问题,但是无论哪个行业都会有站在最顶端的那群人。我们要做的就是努力提升自己,让自己站在最顶端,学历不够那就去读,知识不够那就去学。人之所以为人,不就是有解决问题的能力吗?挡住自己的由于只有自己。
Android希望=技能+面试
- 技能
- 面试技巧+面试题
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
| 3.2 | 3.2.0 | 引入 R8、D8 脱糖默认开启 |
| 3.4 | 3.4.0 | 默认开启 R8 |
1.1 D8 编译器
Google
在 Android Studio 3.1
版本中引入 D8
编译器作为默认的 DEX
字节码文件编译器。通过在 gradle.properties
中新增 android.enableD8=true
开启 D8
编译器。
D8
编译器特点是:
- 编译更快、时间更短;
DEX
编译时占用内容更小;.dex
文件大小更小;D8
编译的.dex
文件拥有相同或者是更好的运行时性能;
根据 Google Android
团队使用 Dex
与 D8
编译器的测试对比数据:
1.2 R8 工具
Google
在 Android Studio 3.2
中引入 R8
作为 ProGuard
的替代工具,用于代码的压缩(shrinking
)和混淆(obfuscation
)。通过在 gradle.properties
中新增 android.enableR8 = true
开启 R8
工具。
Disables R8 for Android Library modules only.
android.enableR8.libraries = false
Disables R8 for all modules.
android.enableR8 = false
1.3 Android Studio 3.4 版本 D8 R8 变更
在 Android Studio 3.4
版本中,R8
把 desugaring
、shrinking
、obfuscating
、optimizing
和 dexing
都合并到一步进行执行。在 Android Studio 3.4
以前的版本编译流程如下:
合并之后编译流程如下:
注意,如果我们在 build.gradle
中配置了 useProguard = false
则不管是否开启 R8
编译都会使用 R8
进行压缩代码。
2. 脱糖
Android Studio
为使用部分 Java 8
语言功能及利用这些功能的第三方库提供内置支持。默认工具链对 javac
编译器的输出执行字节码转换(称为 desugar
),从而实现新语言功能。
脱糖即在编译阶段将在语法层面一些底层字节码不支持的特性转换为基础的字节码结构,(比如 List
上的泛型脱糖后在字节码层面实际为 Object
); Android
工具链对 Java8
语法特性脱糖的过程可谓丰富多彩,当然他们的最终目的是一致的:使新的语法可以在所有的设备上运行。
经过上面 D8
、R8
的了解,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);
}
@FunctionalInterface
interface Logger {
void log(String msg);
}
}
通过 javac
指令将上面的 Lambda.java
转换为字节码。
$javac Lambda.java
接下来通过 javap -v
指令查看字节码的详细内容:
dengshiweideMacBook-Pro:Desktop dengshiwei$ javap -v Lambda.class
Classfile /Users/dengshiwei/Desktop/Lambda.class
Last modified 2019-5-12; size 1120 bytes
MD5 checksum 67301305720e60d4ef1ff286769768e6
Compiled from “Lambda.java”
public class Lambda
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #9.#25 // java/lang/Object.“”😦)V
#2 = InvokeDynamic #0:#30 // #0:log:()LLambdaKaTeX parse error: Expected 'EOF', got '#' at position 9: Logger; #̲3 = String …Logger;Ljava/lang/String;)V
#5 = InterfaceMethodref #10.#33 // LambdaKaTeX parse error: Expected 'EOF', got '#' at position 34: …lang/String;)V #̲6 = Fieldref …Logger
#11 = Utf8 Logger
#12 = Utf8 InnerClasses
#13 = Utf8
#14 = Utf8 ()V
#15 = Utf8 Code
#16 = Utf8 LineNumberTable
#17 = Utf8 main
#18 = Utf8 ([Ljava/lang/String;)V
#19 = Utf8 logDebug
#20 = Utf8 (LLambdaKaTeX parse error: Expected 'EOF', got '#' at position 29: …lang/String;)V #̲21 = Utf8 …mainKaTeX parse error: Expected 'EOF', got '#' at position 3: 0 #̲22 = Utf8 …Lookup;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.lambda$mainKaTeX parse error: Expected 'EOF', got '#' at position 25: …lang/String;)V #̲30 = NameAndTyp…Logger;
#31 = Utf8 HelloWorld
#32 = NameAndType #19:#20 // logDebug:(LLambdaKaTeX parse error: Expected 'EOF', got '#' at position 29: …lang/String;)V #̲33 = NameAndTyp…Logger
#41 = Methodref #50.#51 // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandlesKaTeX parse error: Expected 'EOF', got '#' at position 173: …voke/CallSite; #̲42 = Methodref …mainKaTeX parse error: Expected 'EOF', got '#' at position 25: …lang/String;)V #̲43 = Utf8 …Logger;
#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/MethodHandlesKaTeX parse error: Expected 'EOF', got '#' at position 173: …voke/CallSite; #̲52 = NameAndTyp…mainKaTeX parse error: Expected 'EOF', got '#' at position 25: …lang/String;)V #̲53 = Utf8 …Lookup
#56 = Utf8 Lookup
#57 = Utf8 (Ljava/lang/invoke/MethodHandlesKaTeX parse error: Expected 'EOF', got '#' at position 173: …voke/CallSite; #̲58 = Class …Lookup
#60 = Utf8 java/lang/invoke/MethodHandles
{
public Lambda();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object.“”😦)V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: invokedynamic #2, 0 // InvokeDynamic #0:log:()LLambda$Logger;
最后
针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!