Android 编译期的黑科技(一)基础篇
序言
- 为什么需要这些编译期的黑科技 使用这些编译期的小工具可以有效减少 重复代码和重复逻辑 在android中大量运用的ButterKnife Gilde Room和DataBind都大量的时候用编译期生成代码的技术
- 哪里可以用到这些 应用场景很多 最经典的应用场景是无痕埋点技术和解决重复逻辑
- 为什么需要这个基础篇 直接上工具当然也可以使用,但毕竟写代码 知其然还要知其所以然 不然除了各种问题无法解决就很尴尬了
什么是编译
它主要的目的是将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序,也就是可执行文件。编译器将原始程序(source program)作为输入,翻译产生使用目标语言(target language)的等价程序。源代码一般为高级语言(High-level language),如Pascal、C、C++、C# 、Java等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)。 java编译专指 .java —>.class
编译器做了什么事
java 编译流程
此节大部分内容源自《深入理解jvm虚拟机》
解析与填充符号表->注解处理->分析与字节码生成
javac 编译过程
解析与填充符号表
- 词法语法分析 根据token序列构造抽象语法树
- 填充符号表
注解处理
这个阶段是我们可以控制编译的重点阶段,可以读取修改添加抽象语法树的任意元素
分析与字节码生成
最后这个阶段就是从抽象语法书生成.class的阶段了
- 标注检查
- 数据以及控制流分析
- 解语法糖
- 生成字节码
编译优化
在编译的过程中 编译期也对一些必要的地方进行了优化
- 自动拆装箱 遍历循环
- 条件编译 例如
if(true){
System.out.println("true");
}else {
System.out.println("false");
}
System.out.println(“false”)这句会被自动省略
Android的编译器多做了什么事
我们都知道是世界上在Dalvik/ART中运行的并不是.class 而是.dex 那么在这中间又发生了什么呢
- 因为.class文件包含大量陈余信息,dex文件格式会把所有的.class文件内容整合到一个.dex文件中。即减少了整体文件的尺寸和IO操作,也提高了类的查找速度。
- 增加了对新的操作码的支持
- 文件结构尽量简洁,使用等长的指令,借以提高解析速度。
- 尽量扩大只读结构的大小,借以提高跨进程的数据共享。
- 对一些特定的类和方法里面的操作码进行优化
- 调整所有的字节序(Little_endian)和对齐结构中的每一个域
- 验证dex文件中的所有类 如果一个类引用到的所有非系统类都在同一个dex文件中这个类会被打上标记 加快解析速度 (热修复技术会被这个问题整的很惨)