Android 编译期的黑科技(一)基础篇

序言

  1. 为什么需要这些编译期的黑科技 使用这些编译期的小工具可以有效减少 重复代码和重复逻辑 在android中大量运用的ButterKnife Gilde Room和DataBind都大量的时候用编译期生成代码的技术
  2. 哪里可以用到这些 应用场景很多 最经典的应用场景是无痕埋点技术和解决重复逻辑
  3. 为什么需要这个基础篇 直接上工具当然也可以使用,但毕竟写代码 知其然还要知其所以然 不然除了各种问题无法解决就很尴尬了

什么是编译

它主要的目的是将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序,也就是可执行文件。编译器将原始程序(source program)作为输入,翻译产生使用目标语言(target language)的等价程序。源代码一般为高级语言(High-level language),如Pascal、C、C++、C# 、Java等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)。 java编译专指 .java —>.class

编译器做了什么事

java 编译流程

此节大部分内容源自《深入理解jvm虚拟机》 Alt text 解析与填充符号表->注解处理->分析与字节码生成 javac 编译过程

解析与填充符号表

  1. 词法语法分析 根据token序列构造抽象语法树
  2. 填充符号表

注解处理

这个阶段是我们可以控制编译的重点阶段,可以读取修改添加抽象语法树的任意元素

分析与字节码生成

最后这个阶段就是从抽象语法书生成.class的阶段了

  1. 标注检查
  2. 数据以及控制流分析
  3. 解语法糖
  4. 生成字节码

编译优化

在编译的过程中 编译期也对一些必要的地方进行了优化

  1. 自动拆装箱 遍历循环
  2. 条件编译 例如
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文件中这个类会被打上标记 加快解析速度 (热修复技术会被这个问题整的很惨)