Android Studio 的 build 过程

我们知道,在 Android 项目的开发过程中,只需要点一下 Android Studio 的运行按钮,就可以将代码编译好并运行在设备上。相信任何一个 Android 开发者都知道,从我们点击按钮到设备上运行 APP,Android Studio 默默地做了编译、打包(生成 APK 文件)、安装、运行等很多事情,安装和运行不是本文所关心的内容。下面,我们一起来看看,Android Studio 的编译、打包(也可以合并称为构建)过程。

构建流程

先来看下 Android 官网给出的构建流程图:

**图 1.** 典型 Android 应用模块的构建流程

如图 1 所示,典型 Android 应用模块的构建流程通常依循下列步骤:

  1. 编译器源代码(包括 Application Module 及其所依赖的所有 Library 源代码)转换成 DEXDalvik Executable)文件(其中包括运行在 Android 设备上的字节码),将所有其他内容转换成已编译资源
  2. APK 打包器DEX 文件和已编译资源合并成单个 APK。不过,必须先对 APK 签名,才能将应用安装并部署到 Android 设备上。
  3. APK 打包器使用 Debug 或 Release 密钥库对 APK 签名:
    • 如果您构建的是 Debug 版本的应用(即专用于测试和分析的应用),`打包器`会使用 Debug 密钥库签名应用。Android Studio 自动使用 Debug 密钥库配置新项目。
    • 如果您构建的是打算向外发布的 Release 版本应用,`打包器`会使用 Release 密钥库签名应用。
  4. 在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,减少其在设备上运行时的内存占用。

构建流程结束后,得到可用来进行部署、测试的 Debug APK,或者可用来发布给外部用户的 Release APK

本段内容参考 Android 官网(需科学上网,不能科学上网的童鞋点这里

上面 Android 官方只是给出了 Android 大致的构建流程,并没有详细,下面通过实际构建来看一下,Android Studio 的 build 过程。

Gradle 构建 tasks 说明

我们通过 Android Studio 的 build -> Build APK 功能来看下,build 过程中是怎样的。Build APK 会执行以下 Gradle task。 (注:这里是用 Debug 模式做例子,Release 模式时只需将 task 中的 Debug 替换成 Release 理解即可)

Executing tasks: [:app:assembleDebug]

:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:transformDataBindingBaseClassLogWithDataBindingMergeGenClassesForDebug UP-TO-DATE
:app:dataBindingGenBaseClassesDebug UP-TO-DATE
:app:checkDebugManifest UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:prepareLintJar UP-TO-DATE
:app:mainApkListPersistenceDebug UP-TO-DATE
:app:createDebugCompatibleScreenManifests UP-TO-DATE
:app:processDebugManifest
:app:splitsDiscoveryTaskDebug UP-TO-DATE
:app:processDebugResources
:app:generateDebugSources
:app:dataBindingExportBuildInfoDebug
:app:javaPreCompileDebug UP-TO-DATE
:app:transformDataBindingWithDataBindingMergeArtifactsForDebug UP-TO-DATE
:app:compileDebugJavaWithJavac
:app:compileDebugNdk NO-SOURCE
:app:compileDebugSources
:app:mergeDebugShaders UP-TO-DATE
:app:compileDebugShaders UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:transformClassesWithDexBuilderForDebug
:app:transformDexArchiveWithExternalLibsDexMergerForDebug
:app:transformDexArchiveWithDexMergerForDebug
:app:mergeDebugJniLibFolders UP-TO-DATE
:app:transformNativeLibsWithMergeJniLibsForDebug UP-TO-DATE
:app:processDebugJavaRes NO-SOURCE
:app:transformResourcesWithMergeJavaResForDebug UP-TO-DATE
:app:validateSigningDebug UP-TO-DATE
:app:packageDebug
:app:assembleDebug


BUILD SUCCESSFUL in 20s

特别说明:由于 Gradle 会尝试通过不重复执行输入未发生变化的 task 来节省时间(这些 task 被标记为 UP-TO-DATE,如上所示)

上面列出来的 Gradle 构建过程,大致可分为五个阶段

  1. Preparation of dependecies 在这个阶段 Gradle 检测 Module 依赖的所有 library 是否 ready。如果这个 Module 依赖于另一个 Module ,则另一个 Module 也要被编译。
  2. Merging resources and processing Manifest 打包资源Manifest 文件。
  3. Compiling 在这个阶段处理编译器的注解源码被编译成字节码
  4. Postprocessing 所有带 transform 前缀的 task 都是这个阶段进行处理的。
  5. Packaging and publishing 这个阶段 library 生成.aar文件,Application 生成.apk文件。

这五个阶段和上面的构建过程中 task 的时序有大致的对应关系,大家可以相互映照着理解。

为了便于大家理解,下面给出一些关键 task 的说明:

  • mergeDebugResources 解压所有的 aar 包输出到app/build/intermediates/exploded-aar,并且把所有的资源文件合并到app/build/intermediates/res/merged/debug目录里。

  • processDebugManifest 把所有 aar 包里的AndroidManifest.xml中的节点,合并到项目的AndroidManifest.xml中,并根据app/build.gradle中当前buildType 的 manifestPlaceholders配置内容替换 manifest 文件中的占位符,最后输出到app/build/intermediates/manifests/full/debug/AndroidManifest.xml

  • processDebugResources

    1. 调用 aapt 生成项目和所有 aar 依赖的R.java,输出到app/build/generated/source/r/debug目录;
    2. 生成资源索引文件app/build/intermediates/res/debug/resources-debug.ap_
    3. 符号表输出到app/build/intermediates/symbols/debug/R.txt
  • compileDebugJavaWithJavac 用来把 java 文件编译成 class 文件,输出的路径是app/build/intermediates/classes/debug

    编译的输入目录有

    • 项目源码目录,默认路径是app/src/main/java,可以通过 sourceSetsdsl 配置,允许有多个(打印project.android.sourceSets.main.java.srcDirs可以查看当前所有的源码路径,具体配置可以参考 android-doc,以及这里
    • app/build/generated/source/aidl
    • app/build/generated/source/buildConfig
    • app/build/generated/source/apt(继承javax.annotation.processing.AbstractProcessor做动态代码生成的一些库,输出在这个目录)的代码。
  • transformClassesWithMultidexlistForDebug这个任务在使用 Multidex 才会出现)它有两个作用

  • 扫描项目的AndroidManifest.xml文件和分析类之间的依赖关系,计算出那些类必须放在第一个 dex 里面,最后把分析的结果写到app/build/intermediates/multi-dex/debug/maindexlist.txt文件里面

  • 生成混淆配置项输出到app/build/intermediates/multi-dex/debug/manifest_keep.txt文件里

    项目里的代码入口是 manifestapplication 节点的属性 android.name 配置的继承自 Application 的类,在 Android 5.0 以前的版本系统只会加载一个 dex(classes.dex),classes2.dex …….classesN.dex 一般是使用android.support.multidex.MultiDex加载的,所以如果入口的 Application 类不在 classes.dex5.0 以下肯定会挂掉,另外当入口 Application 依赖的类不在 classes.dex 时初始化的时候也会因为类找不到而挂掉,还有如果混淆的时候类名变掉了也会因为对应不了而挂掉,综上所述就是这个任务的作用。

总结

简而言之,Android Studio 的构建构成总结为以下几点:

  • 源代码(包括 Application Module 和 Library Module)编译成 class 文件,再将所有的 class 文件(包括第三方库中)打包生成 dex 文件。
  • 解压所有 aar 包中的资源文件,并和项目中所有资源文件合并到一个目录。
  • 生成资源文件的索引文件。
  • 最终将所有的dex文件和已编译的资源文件,打包生成.apk文件。

到这里,大家再次对照上面的流程图,联合理解,相信会有一种明悟的赶脚

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio是谷歌官方推出的用于开发Android应用程序的集成开发环境(IDE)。而Build Tools是Android Studio中的一部分,它提供了一系列用于构建和编译Android应用的工具。 Android Studio Build Tools主要包括以下几个部分: 1. AAPT (Android Asset Packaging Tool):这是一个资源打包工具,负责将应用程序中的各种资源(如布局文件、图像、音频等)进行编译、压缩和处理,生成最终的资源二进制文件。 2. D8 (Dexer):这是一个将Java字节码转换为Dalvik字节码的dex编译器。它能够将Java代码编译为Dalvik虚拟机能够执行的dex文件,以便在Android设备上运行。 3. ProGuard:这是一个代码混淆工具,用于减小APK文件的大小,并保护应用程序的源代码免受逆向工程的威胁。它将不必要的代码删除、变量名重命名以及其他优化操作。 4. Android Gradle插件:这是一个与Gradle构建系统集成的插件。它利用Gradle的强大功能来自动化构建过程,包括编译、打包和签名应用程序。它还支持多种构建变体和产品风味,以适应不同的设备和市场需求。 借助Android Studio Build Tools,开发人员可以更加高效地构建和调试他们的Android应用程序。这些工具提供了必要的功能和优化,可以帮助开发人员创建高质量、高性能的应用。同时,Build Tools还与Android SDK紧密集成,提供了丰富的API和功能,帮助开发人员轻松地开发出功能丰富的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值