Android Studio 的 build 过程

如图,
编译器将源代码(包括 Application Module 及其所依赖的所有 Library 源代码)转换成DEX(Dalvik Executable)文件(其中包括运行在 Android 设备上的字节码),将所有其他内容转换成已编译资源。(- 将源代码(包括 Application Module 和 Library Module)编译成 class 文件,再将所有的 class 文件(包括第三方库中)打包生成 dex 文件。
- 解压所有 aar 包中的资源文件,并和项目中所有资源文件合并到一个目录。
- 生成资源文件的索引文件。
)
APK 打包器将 DEX 文件和已编译资源打包生成单个 APK。不过,必须先对 APK 签名,才能将应用安装并部署到 Android 设备上。APK 打包器使用 Debug 或 Release 密钥库对 APK 签名:- 如果您构建的是 Debug 版本的应用(即专用于测试和分析的应用),
打包器会使用 Debug 密钥库签名应用。Android Studio 自动使用 Debug 密钥库配置新项目。 - 如果您构建的是打算向外发布的 Release 版本应用,
打包器会使用 Release 密钥库签名应用。
- 如果您构建的是 Debug 版本的应用(即专用于测试和分析的应用),
- 在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,减少其在设备上运行时的内存占用。
2. Gradle 构建 tasks 说明
注:这里是用 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 构建过程,大致可分为五个阶段:
Preparation of dependecies在这个阶段 Gradle 检测 Module 依赖的所有 library 是否 ready。如果这个 Module 依赖于另一个 Module ,则另一个 Module 也要被编译。Merging resources and processing Manifest打包资源和 Manifest 文件。Compiling在这个阶段处理编译器的注解,源码被编译成字节码。Postprocessing所有带 transform 前缀的 task 都是这个阶段进行处理的。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- 调用 aapt 生成项目和所有 aar 依赖的
R.java,输出到app/build/generated/source/r/debug目录; - 生成资源索引文件
app/build/intermediates/res/debug/resources-debug.ap_; - 把符号表输出到
app/build/intermediates/symbols/debug/R.txt。
- 调用 aapt 生成项目和所有 aar 依赖的
compileDebugJavaWithJavac用来把 java 文件编译成 class 文件,输出的路径是app/build/intermediates/classes/debug编译的输入目录有
- 项目源码目录,默认路径是
app/src/main/java,可以通过 sourceSets 的 dsl 配置,允许有多个(打印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文件里
项目里的代码入口是 manifest 中 application 节点的属性 android.name 配置的继承自 Application 的类,在 Android 5.0 以前的版本系统只会加载一个 dex(classes.dex),classes2.dex .......classesN.dex 一般是使用
android.support.multidex.MultiDex加载的,所以如果入口的 Application 类不在 classes.dex 里 5.0 以下肯定会挂掉,另外当入口 Application 依赖的类不在 classes.dex 时初始化的时候也会因为类找不到而挂掉,还有如果混淆的时候类名变掉了也会因为对应不了而挂掉,综上所述就是这个任务的作用。- 扫描项目的
Android Studio 的 build 过程的更多相关文章
- 使用Android Studio调试UiAutomator过程中遇到的问题
声明: 这里纪录了个人学习和使用Android Studio调试UiAutomator过程中遇到遇到的问题,不定时进行更新,欢迎一起交流学习 1.Excution faild for task ‘:a ...
- Android studio在使用过程中的问题总汇!
使用android studio也有一段时间了,汇总了一下这段时间内遇到一些常见问题,希望能够帮助到大家! 一.字体大小问题 在android studio的使用过程中没有发现类似于Eclipse中的 ...
- 解决Android Studio Gradle Build Running慢的问题
Android Studio方便好用,但是Android Studio Gradle Build Running很慢 解决方法: C:\Users\你的用户名\.gradle 目录下新建一个文件名为 ...
- 解决Android Studio Gradle Build特别慢的问题
解决Android Studio Gradle Build 特别慢的问题 C:\Users\你的用户名\.gradle目录下新建一个文件名为gradle.properties的文件.内容为:org.g ...
- Android Studio Gradle Build Running 特别慢的问题探讨
本文的本本win7 64bit 6G android studio2.1 在运行程序的时候Gradle Build Running 特别慢,一个helloworld都快2min了 1.开启gradle ...
- 如何用Android Studio查看build.gradle源码
上一篇博客里讲过 build.gradle 里的每一行代码基本都是在调用一个方法,既然是这样,我们就可以用 android studio(下面简称as) 去查看它源码的方法注释说明,这样就可以理解每个 ...
- 第一次用上 Android Studio 2.3 过程及错误解决
因为要开发Android5.0的缘故,抛弃了eclipse转到了Android Studio,第一次使用就是遇到了许多问题,终于是解决问题了,特意写一篇博文给各位要准备从eclipse转到Androi ...
- Android Studio 出现 Build gradle project info
导入Android Studio,一直停留在Build gradle project info.主要是因为google被墙,下载gradle很慢,有时候设置下载不成功. 参考链接 http://blo ...
- 提高Android Studio的Build速度实践
1.在下面的目录创建gradle.properties文件 /home/<username>/.gradle/ (Linux) /Users/<username>/.gradl ...
随机推荐
- WPF常用TriggerAction用法 (一)
Microsoft.Expression.Interactivity 常用TriggerAction-> CallMethodAction ChangePropertyAction Contro ...
- Robot Framework 自动化框架大纲
Python + Robot Framework 环境搭建 Android SDK + Appium 环境搭建 RobotFramework - AppiumLibrary 之元素定位 RobotFr ...
- python count函数
描述 Python count() 方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. 语法 count()方法语法: str.count(sub, start= 0,e ...
- python:windows下python2.7安装mysql-python失败【转】
转自:https://www.cnblogs.com/yujiebingqing/p/9633476.html 当我们尝试用: 1 pip install mysql-python #并不是MySQL ...
- 菜鸟教程之学习Shell script笔记(上)
菜鸟教程之学习Shell script笔记 以下内容是,学习菜鸟shell教程整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-shell.ht ...
- java中四种修饰符(private、default、protected、public)的访问权限
权限如下: no. 范围 private default protected public 1 同一包下的同一个类 √ √ √ √ 2 同一包下的不同类 × √ √ √ 3 不同包下的子类 × × √ ...
- Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
当我们使用gson 转对象时,并且这个对象中有一些属性是懒加载时如 @Entity @Table(name = "user") public class User { @Id @C ...
- 深入理解Java虚拟机读书笔记4----虚拟机类加载机制
四 虚拟机类加载机制 1 类加载机制 ---概念:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型. -- ...
- Linux上安装jdk,mysql
1.准备工作 一台纯净的Linux系统需要先安装一些依赖才能安装jdk等 rpm: 本地添加安装程序:rpm -ivh 程序名 本地查看程序: rpm -qa 本地卸载程序: rpm -e --nod ...
- if __name__ == '__main__':用法
这个博主写的很好,已经验证过了.https://blog.csdn.net/yjk13703623757/article/details/77918633