本节基于Android 构建系统概览和从 Android Studio 构建并运行来展示如何基于产品口味和构建类型来使用构建变种。
构建配置基础
Android Studio 项目包含一个顶级的构建文件以及每个模块下的一个构建文件。构建文件名为 build.gradle
,他们是普通的文本文件,通过 Gradle 的 Android 插件提供的元素,使用 Groovy 语法来配置构建过程。大多数情况下,你只需要在模块层级上来编辑构建文件。例如在项目 BuildSystemExample
的 app 模块的构建文件看起来像这样:
1 | apply plugin: 'com.android.application' |
apply plugin: 'com.android.application'
说明应用 Gradle 的 Android 插件来构建。这将为顶级的构建任务新增 Android 指定的构建任务,并添加 android {...}
元素为 Android 指定的构建选项。
android {...}
则配置所有 Android 指定的构建选项:
compileSdkVersion
属性指定编译目标版本。buildToolVersion
属性指定采用那个版本的构建工具。想要安装不同版本的构建工具,可以使用 SDK 管理器。
注意: 永远要使用版本号比你所用的编译目标或者目标 SDK 的主要修订号高的或者相等的构建工具。
defaultConfig
元素动态地配置构建系统中的清单文件(AndroidManifest.xml
)的核心设置和条目。defaultConfig
中的值将覆盖清单文件中的对应值。defaultConfig
元素中的指定配置将被应用到所有构建变种,除非某个构建变种的配置覆盖了其中的一些值。buildTypes
元素控制如何构建和打包应用程序。 构建系统默认定义了两个构建类型: debug 和 release。 debug 构建类型包含调试标志,并使用 debug 密钥签名。 release 构建类型默认是为签名的。这个实例中构建文件配置了 release 版本使用混淆。
dependencies
元素位于 android
元素之外,在其后面。该元素申明这个模块的依赖。依赖将在后面的章节中说明。
注意: 当你修改了项目中的构建文件, Android Studio 需要一个项目同步来导入构建配置的改变。点击出现在 Android Studio 黄色通知栏上的 Sync Now 按钮来导入这些变化。
声明依赖
实例中的 app 模块声明了3个依赖:
1 | ... |
每种依赖将在下面描述。构建系统添加所有的 compile
依赖到编译类路径中,并在最终的安装包中包含他们。
模块依赖
app
模块依赖 lib
模块,因为如从一个库模块中开启 Activity 中 MainActivity
启动 LibActivity1
。
compile project(":lib")
声明对 BuildSystemExample
中 lib
模块的依赖。当你构建 app
模块时,构建系统将组装和包含 lib
模块。
远程二进制依赖
app
和 lib
模块都使用 Android Support 库中的 ActionBarActivity
类,所以这些模块依赖于它。
compile 'com.android.support:appcompat-v7:19.0.1'
通过指定 Android Support 库的 Maven 坐标来声明对该库 19.0.1 版本的依赖。Android Support 库被打包在 Android SDK 的 Android 仓库中。如果你安装的 SDK 中不包含该安装包,可以通过 SDK 管理器来下载并安装。
Android Studio 默认配置项目使用 Maven 中央仓库。(该配置包含在项目的顶级构建文件中)。
本地二进制依赖
一些模块没有用到本地文件系统的任何二进制依赖。如果你拥有一些模块需要本地二进制依赖,复制这些依赖中的 JAR 文件 到你项目中的 <moduleName>/libs
目录下。
compile fileTree(dir: 'libs', include: ['*.jar'])
告诉构建系统所有 app/libs
下的 JAR 文件都是依赖,将被包含在编译类路径和最终安装包中。
想了解 Gradle 的依赖更多信息,查看 Gradle 用户指南中的以来管理基础。
运行混淆
构建系统可以在构建过程中运行 ProGuard 来混淆类,通过修改 app
模块中的构建文件来为 release 构建运行 ProGuard:
1 | ... |
getDefaultProguardFile('proguard-android.txt')
从 Android SDK 安装路径下获取默认的 ProGuard 设置。 Android Studio 在模块根目录下添加模块指定的规则文件 proguard-rules.pro
, 这样你可以添加自定义的 ProGuard 规则。
安装包标识:应用程序ID
在 Android 构建系统中, applicationId 属性是用来唯一标识发布的应用程序包的。 applicationId 在 build.gradle
文件中的 android 部分设置。
1 | apply plugin: 'com.android.application' |
注意: applicationId 只能在
build.gradle
文件中指定,而不能在 AndroidManifest.xml 中。
在使用构建变种时,构建系统允许为每个产品修饰和构建类型唯一的标识不同的安装包。 构建类型中的 applicationId 被添加为后缀,以便指定产品修饰。
1 | productFlavors { |
清单文件中依然要指定包名。它将用来在代码只能怪引用 R 类,并解决一些相对的 activity/service 的注册。
1 | package="com.example.app"> |
注意: 如果存在多个清单文件(例如一个产品修饰指定的清单和一个构建类型清单),包名在这些清单中是可选的。如果在这些清单中指定包名,这些包名应该和
src/main
文件夹下的清单中的包名完全一样。
想了解构建文件和过程的更多信息,查看 Android 构建系统概览。
配置签名设置
debug 和 release 版本的应用区别在于是否应用程序能够在安全设备上被调试以及 APK 如何被签名。构建系统使用默认的密钥和已知证书的凭证来签名 debug 版本以避免在构建时密码提醒。构建系统不会签名 release 版本,除非为这次构建明确定义一个签名配置。如果你还没有 release 密钥,可以像签名应用程序中一样,自己生成一个。
使用构建变种工作
这一章节描述构建系统如何从单一的项目来创建相同应用程序的不同版本。当你的应用程序存在一个 Demo 版本和一个付费版本,或者在 Google Play 上针对不同配置的设备发布多个 Apk 包时,这将变得非常有用。
构建系统使用产品口味来创建应用程序的不同产品版本。每个产品版本可以有不同的功能和设备要求。构建系统同时使用构建变形来应用不同的构建和打包设置到每个产品版本。每个产品口味和构建类型组合形成构建变种。构建系统则为应用程序的每个构建变种生成不同的 APK。
构建变种
这个实例项目包含两个默认的构建类型( debug 和 release )和两个对应应用类型( demo 和 full)的 产品口味。构建变种的更多高级用法,请查看 Android 构建系统概览。
产品口味
创建应用程序的不同产品版本:
- 在构建文件中定义产品口味。
- 为每种口味创建额外的源文件夹。
- 添加特定口味的源文件到应用程序中。
接下来的部分使用 BuildSystemExample
项目来详细介绍这些过程。为 BuildSystemExample
应用创建两种口味,一个 demo 和一个 full。两种口味共享 MainActivity
,在这个 Activity 中添加一个按钮来启动一个新的 SecondActivity
。这个新的 Activity 则在不同变种中不同,因此你可以模拟这样的状态:让 full 口味的新 Activity 具有比 demo 口味更多的功能。在练习的最后,你将得到两个不同的 APK 包,每种口味一个。
在构建中定义产品口味
要定义两种产品口味,编辑 app
模块的构建文件来添加下面的配置。
1 | ... |
产品口味定义支持相同的属性,如 defaultConfig
元素。所有口味的基础配置在 defaultConfig
中指定,每种口味可以覆盖任何的默认值。这个构建文件使用 applicationId
属性为每种口味分配不同的包名:因为每种口味定义创建一个不同的应用程序,每个应用程序需要区分包名。
注意: 使用多 APK 支持在 Google Play 市场发布应用程序,需要为所有的变种分配相同的包名和不同的
versionCode
。要发布不同变种为 Google Play 上的独立应用,则要为每个变种分配不同的包名。
为每个变种创建额外的源文件夹
创建源文件夹,并为每种口味添加 SecondActivity
。为 demo 口味创建源文件夹结构:
- 在
Project
面板,展开BuildSystemExample
,然后展开app
目录。 - 右击
app
目录下的src
文件夹并选择 New > Direcory。 - 输入 “demo” 作为新文件夹名称,并点击 OK。
- 类似地步骤,创建下面的文件夹:
app/src/demo/java
app/src/demo/res
app/src/demo/res/layout
app/src/demo/res/values
最终的目录结构如下图:
为每种口味添加新的 Activity
添加 SecondActivity
到 demo 口味:
- 在
Project
面板,右击app
模块并选择 New > Activity。 - 选择 Blank Activity 并点击 Next。
- 输入 “SecondActivity” 作为 Activity 名称。
- 输入 “com.buildsystemexample.app” 作为包名并点击 Finish。
- 右击 app/src/demo 下的 java 目录,并选择 New > Package。
- 输入 “com.buildsystemexample.app” 作为包名并点击 OK。
- 拖动 SecondActivity,并将其放到 app/src/demo/java 下的新包中。
- 接受默认值并点击 Refactor。
添加 SecondActivity 的布局和字符串资源到 demo 口味:
- 从 app/src/main/res/layout 拖动 activity_second.xml 到 app/src/demo/res/layout 中。
- 接受窗口中出现的默认值并点击 OK。
- 从 app/src/main/res 复制 strings.xml 到 app/src/demo/res 中。
- 用下面的内容替换 strings.xml 新副本中的内容。
1 | "1.0" encoding="utf-8" xml version= |
接下来通过复制 demo 口味来添加源文件夹和 SecondActivity
到 full 口味:
- 在
Project
面板,右击 app/src 下的 demo 目录,并选择 Copy。 - 右击 app/ 下的 src/ 目录,并选择 Paste。
- 当窗口出现是,输入 full 作为新的名字,并 OK。
- 使用下面的内容替换 src/full/res/values 下的 strings.xml 的内容:
1 | "1.0" encoding="utf-8" xml version= |
注意:从现在开始,你可以在每种口味上独立的开发
SecondActivity
。例如,你可以在 full 口味中为这个 Activity 添加更多的功能。
想要在特定口味上的文件进行工作,点击 IDE 窗口左上角的 Build Variants,并在”构建变种”面板选择你想要修改的口味,如下图所示。 Android Studio 会为没有在构建变种面板上选中的口味的源文件中显示错误,但是这不影响构建输出。
从主 Activity 启动特定口味的 Activity
由于特定口味的 Activity (SecondActivity
)在两种口味中拥有相同的包名和 activity 名称,可以从所有口味共同的主 Activity 中启动它。修改主 Activity 如下:
1、 编辑 activity_main.xml
,并添加新的按钮到 MainActivity
:
1 | <LinearLayout ...> |
2、 点击布局文件中标记为红色的区域并点击 Alt + Enter。按照 Android Studio 的提示添加一个值为 “Open Second Activity” 的字符串资源,以及 onButton2Clicked
方法到 MainActivity
。
3、 添加下面的代码到 MainActivity
中的 onButton2Clicked
方法:
1 | public void onButton2Clicked(View view) { |
4、 编辑应用的 manifest 文件来包含 SecondActivity
的引用:
1 | <manifest ...> |
构建类型
构建类型代表了为每个应用程序构建打包的版本。默认系统提供了 debug 和 release 的构建类型。
1 | ... |
注意:虽然只有 release 的构建类型出现在默认的 build.gradle 文件中,但每个构建都提供了 release 和 debug 的构建类型。
在这个实例中,产品口味和构建类型创建了下面的构建变种:
- demoDebug
- demoRelease
- fullDebug
- fullRelease
要构建这个实例,点击 Android Studio 上的 Build 选项按钮,或者从命令行调用 assemble
任务。
注意: Build > Make Project 选项将编译整个项目中自从上一次编译之后所有被修改过的源文件。Build > Rebuild Project 选项将重新编译项目中的所有源文件。
每个构建变种将创建独立的输出文件夹。