编译是什么?

将高级语言转化为机器或者虚拟机所能识别的低级语言的过程。对于 Android 来说,这个过程就是把 Java 或者 Kotlin 转变为 Android 虚拟机运行的Dalvik 字节码的过程。

Android编译相关知识(https://developer.android.com/studio/build/?hl=zh-cn)

Gradle 和 Android 插件独立于 Android Studio 运行。(这意味着,您可以在 Android Studio 内、计算机上的命令行或未安装 Android Studio 的计算机(如持续集成服务器)上构建 Android 应用。)

Android Studio (Gradle 插件)

Gradle 插件 和 Gradle 版本有对应关系

AAPT2(https://developer.android.com/studio/command-line/aapt2)

Android Studio 和 Android Gradle 插件使用它来编译和打包应用的资源。AAPT2 会解析资源、为资源编制索引,并将资源编译为针对 Android 平台进行过优化的二进制格式。
AAPT2 支持通过启用增量编译实现更快的资源编译

AAPT2的编译过程
1.AAPT2 支持编译所有 Android 资源类型,如可绘制对象和 XML 文件。调用 AAPT2 进行编译时,每次调用都应传递一个资源文件作为输入。然后,AAPT2 会解析该文件并生成一个扩展名为 .flat 的中间二进制文件。

zipalign

zipalign 是一种归档对齐工具,可对 Android 应用 (APK) 文件提供重要的优化。其目的是要确保所有未压缩数据的开头均相对于文件开头部分执行特定的对齐。具体来说,它会使 APK 中的所有未压缩数据(例如图片或原始文件)在 4 字节边界上对齐。这样一来,即可使用 mmap() 直接访问所有部分,即使其中包含具有对齐限制的二进制数据也没关系。这样做的好处是可以减少运行应用时消耗的 RAM 容量。

注意:您必须在应用构建过程中的两个特定时间点之一使用 zipalign,具体在哪个时间点使用,取决于您所使用的应用签名工具:
如果您使用的是 [apksigner](https://developer.android.com/studio/command-line/apksigner),只能在为 APK 文件签名之前执行 zipalign。如果您在使用 apksigner 为 APK 签名之后对 APK 做出了进一步更改,签名便会失效。
如果您使用的是 [jarsigner](https://docs.oracle.com/javase/tutorial/deployment/jar/signing.html),只能在为 APK 文件签名之后执行 zipalign。

编译过程

  1. 通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)
  2. 处理.aidl文件,生成对应的Java接口文件
  3. 通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件
  4. 代码混淆(proguard)
  5. 通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex
  6. 通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk
  7. 通过Jarsigner工具,对上面的apk进行debug或release签名
  8. 通过zipalign工具,将签名后的apk进行对齐处理。

https://juejin.im/post/6844903555795517453#heading-2

作者:Jensen121
链接:https://juejin.im/post/6844903555795517453
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如何优化编译速度(https://developer.android.com/studio/build/optimize-your-build?hl=zh-cn#optimize)

1.使用最新版本工具
2.关闭分析工具
3.减少需要编译的资源,关闭Png的压缩
4.使用编译缓存,
5.webp可以有更快的压缩很好的性能
6.增量编译

AAPT2(Android 资源打包工具)是一种构建工具(支持增量 编译)
https://developer.android.com/studio/command-line/aapt2
Gradle
https://developer.android.com/studio/build/?hl=zh-cn
Gradle 插件
https://developer.android.com/studio/releases/gradle-plugin?hl=zh-cn#updating-plugin

比较好的编译过程文章
https://juejin.im/post/6844903555795517453#heading-2
https://segmentfault.com/a/1190000004916563
https://juejin.im/post/6875482712078024711

简单的gradle 语法
https://juejin.im/entry/6844903443170082823

Groovy 是一门JVM 语言,也就是,Groovy 的代码最终也会被编译成JVM 字节码,交给虚拟机去执行

  1. 定义变量
  2. def name = 'Andy'
  3. 变量插值
  4. def name = 'Andy'
  5. def greeting = "Hello, $name!"
  6. 定义方法
  7. def square(def num) {
  8. num * num
  9. }
  10. 调用方法是这样的,不需要分号,会默认把最后执行完的当作结果返回
  11. square 4
  12. 定义类
  13. class MyGroovyClass {
  14. String greeting
  15. String getGreeting() {
  16. return 'Hello!'
  17. }
  18. }
  1. 闭包 Groovy 中有一个闭包的概念。闭包可以理解为就是 Java 中的匿名内部类。
  2. def square = { num ->
  3. num * num
  4. }
  5. square 8
  6. 等价于这个参数
  7. 如果只有一个参数,我们甚至可以省略这个参数,默认使用it作为参数,最后代码是这样的:
  8. Closure square = {
  9. it * it
  10. }
  11. square 16
  12. 理解闭包的语法后,我们会发现,其实在我们之前的配置文件里,
  13. android,dependencies这些后面紧跟的代码块,都是一个闭包而已。