关键词:编译-->DEX-->打包-->签名和对齐
Android工程的编译打包是个复杂的过程,期间既涉及到工程自身的源代码、资源文件、AIDL文件,又涉及到工程所依赖的库文件(Library, JAR, AAR)等,需要由多个工具分多个步骤完成。本文将对编译打包的流程进行描述,并对控制这个流程用到的gradle文件体系进行介绍。
打包过程
下图是谷歌官网给出的一个典型的apk构建的过程,比较概括。主要包括两个过程,首先是编译过程,编译的内容包括本工程的文件以及依赖的各种库文件,编译的输出包括dex文件和编译后的资源文件。然后是打包过程。配合Keystore对第一步的输出进行签名对齐,生成最终的apk文件。
下面这张图对上面的步骤以及每步用到的工具进行了细分,概括如下:
- Java编译器对工程本身的java代码进行编译,这些java代码有三个来源:app的源代码,由资源文件生成的R文件(aapt工具),以及有aidl文件生成的java接口文件(aidl工具)。产出为.class文件。
- .class文件和依赖的三方库文件通过dex工具生成Delvik虚拟机可执行的.dex文件,可能有一个或多个,包含了所有的class信息,包括项目自身的class和依赖的class。产出为.dex文件。
- apkbuilder工具将.dex文件和编译后的资源文件生成未经签名对齐的apk文件。这里编译后的资源文件包括两部分,一是由aapt编译产生的编译后的资源文件,二是依赖的三方库里的资源文件。产出为未经签名的.apk文件。
- 分别由Jarsigner和zipalign对apk文件进行签名和对齐,生成最终的apk文件。
总结为:编译-->DEX-->打包-->签名和对齐
Gradle文件体系
Android工程通过gradle文件管理各项配置,gradle文件利用DSL(Domain Specific Language)语言描述配置,并使用Groovy语言处理编译逻辑。一个典型的Android工程结构如下:
在这里gradle文件分布在几个不同的层级,Project层级以及Module层级。
- Project层级的settings.gradle描述的是该Project包含哪些Module
include ':presentation', ':qamodel', ':chatcommonmodule', ':qa', ':unlimit'
Project层级的build.gradle描述的是作用于所有Module的配置,包括gradle版本等。
- Module层级的build.gradle。每个Module下都有一个作用于该Module的build.gradle文件,描述了该Module相关的配置。这些配置主要包括:BuildTypes,ProductFlavors,Dependency,SigningSettings等。
下面将简要介绍Module层级的build.gradle配置文件。
Configure Build Types
Module层级的gradle文件,buildTypes段。Android会自动在buildTypes段创建release和debug两类配置,debug是默认存在的,并且设置了debuggable true,默认情况下不会展示出来,除非你要修改debug的配置。如下:
android {
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Configure Product Flavors
Module层级的gradle文件,productFlavors段。productFlavors的设置会自动使用defaultConfig配置。如果设置了几个不同的productFlavors,它们会共用defaultConfig配置,以及自己各自的配置,如applicationId。注意,不同的productFlavors都是通过manifest文件里的package属性定义的名字来引用R文件,而不是使用各自的applicationId,所以applicationId其实是可以随意取名的。
android {
...
defaultConfig {
applicationId "com.magic.wdl.simpledaggerdemo"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {...}
productFlavors {
demo {
applicationId "com.magic.wdl.simpledaggerdemo.demo"
versionName "1.0-demo"
}
full {
applicationId "com.magic.wdl.simpledaggerdemo.full"
versionName "1.0-full"
}
}
}
不同的build type和product Flavors可以互相组合,生成m*n种apk文件(不同的Build Variant[版本]),比如:
demoDebug
demoRelease
fullDebug
fullRelease
通过 Build > Select Build Variant可以选择要生成的apk类型。
Configure dependency
dependencies段配置依赖的Module或是本地以及远端的binary。
dependencies {
// Module依赖
compile project(":mylibrary")
// 远端Binary依赖
compile 'com.android.support:appcompat-v7:23.4.0'
// 本地Binary依赖,指定路径app/libs/
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Configure signing settings
signingConfigs段配置签名信息,生成签名的方法参照这里。
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
参考:
https://developer.android.com/studio/build/index.html
http://www.alittlemadness.com/2010/06/07/understanding-the-android-build-process/
http://www.jianshu.com/p/02dfa291d078
http://czak.pl/2016/05/31/handbuilt-android-project.html