有过互联网软件开发经验的朋友一定对于测试环境和生产环境这两个词很是熟悉,在开发和测试阶段,我们常常需要在同一个设备上同时安装着两套甚至多套环境的同一个应用,便于观察调试。所以这篇文章就来和大家分享 Android 利用 Gradle 实现 APP 环境分离的方法。
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
一、环境分离简介
每个 App 项目,至少都会有两个环境:测试环境和生产环境。多的甚至有四个环境:开发环境、测试环境、预生产环境和生产环境。开发人员经常需要在环境之间切换,测试人员也同样。经常出现测试人员今天需要测试环境的最新版本,叫 App 开发人员打包一个给她,明天需要切换到生产版本,再叫 App 开发人员打包一个生产环境的给她。我们知道,一个 App,在一台手机上要么只能是测试环境的,要么只能是生产环境的。测试人员要测试两个环境,只能不断替换不同环境的同个 App,这实在太麻烦了。为了解决此问题,最好的方案就是环境分离,不同环境有不同的 App。
但对于 Android App 来讲,相同包名的 apk 在同一个设备上只能存在一个。所以我们无法做到在同一个设备上同时安装生产环境和测试环境的安装包,这对于日常的开发工作和测试人员的测试工作极不方便。总不能将整个工程复制一份,再通过修改包名的方式打包出另一个 apk 吧。所以在这种情况下,以往常见的做法就是在 app 中提供一个隐形的入口,供内部人员切换服务器地址,然后通过以下代码重启 App:
- private void restartApp(){
- Intent intent = getContext().getPackageManager().getLaunchIntentForPackage(getContext().getPackageName());
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- }
显然,这种做法也只是一种缓兵之计,多少还是有些不尽人意。然而,值得庆幸地是,进入 Android Studio 时代后,Google 开始使用引入 Gradle 构建系统,applicationId 的出现使得环境分离的问题迎刃而解。
二、package 与 applicationId
在使用 Eclipse 开发 Apk 或旧版本的 Gradle 构建系统中,应用的包名由 AndroidManifest.xml 文件中 package 属性决定。同时,这个 package 还被用来定义命名被引用的资源类 R 文件。
但是在新的 Android Gradle 构建系统中,package 属性的两大作用得到了解藕:applicationId 作为应用的唯一标识符(包名),用于区分不同应用;package 属性定义资源类 R 文件,用于引用。
applicationId 存在于 app/build.gradle 文件中的 defaultConfig 配置下,新建项目时默认使用 package 属性值初始化,所以如果没有特殊的需求,一般我们不会在意和修改这个值:
- apply plugin: 'com.android.application'
- android {
- compileSdkVersion 19
- buildToolsVersion "19.1"
- defaultConfig {
- applicationId "com.example.my.app"
- minSdkVersion 15
- targetSdkVersion 19
- versionCode 1
- versionName "1.0"
- }
- ...
所以,要实现 Apk 的环境分离,也就是在同一设备上安装同一应用的不同版本,从本质上我们要修改 applicationId 的值,构建打包出不同包名的 apk 安装文件。Gradle 构建系统提供了两种方式供开发人员修改 applicationId 的值,productFlavors 和 buildTypes,通过这两个方式我们可以轻松实现 apk 的打包定制,或者说 Build Variants(构建变种)。
三、Build Variants
项目的 productFlavors 和 buildTypes 配置可以在 app/build.gradle 代码文件或者 Project Structure 上修改,作用是一样的。
四、productFlavors
项目可以通过定义多个不同的 productFlavors 来实现应用的不同定制版本,每一个 Flavor 与 buildTypes 配合产出对应的一种输出类型的 apk 文件,新建的项目初始化只有一个默认的 Flavor:defaultConfig
注意:默认的 defaultConfig 为新建的 productFlavors 提供基本的配置,也就说,productFlavors 的配置会覆盖 defaultConfig 中相同的属性,从而实现产品的不同定制版输出。对于环境分离,这里可以通过定义新的 applicationId 属性来实现。
五、buildTypes
默认情况下,项目的 buildTypes 包含 debug 和 release 两个构建版本,其中 release 版本的执行需要手动设置签名文件。对于环境分离,与 productFlavors 不同的是,buildTypes 通过定义 applicationIdSuffix 来实现的,即添加后缀名:
除了这些可配置的属性外,productFlavors 和 buildTypes 都会通过各自的 sourceSet 来提供代码和资源,默认的路径为:src/flavorName 和 src/typeName。利用这个特性,我们可以实现不同定制版本的 apk 显示不同的应用名称和桌面图标,以便从设备上进行区分。
productFlavors 和 buildTypes 配合产出各种格式为 "flavorName + typeName" 的 Build Variants,以打包出不同版本的 apk。当你没有自定义 flavors,默认的 defaultConfig 也会与 buildTypes 形成对应的 Build Variants,只是没有名字,所以显示为 debug 和 release。比如这段配置:
- android {
- ...
- productFlavors{
- beta{
- applicationId 'com.yifeng.mdstudysamples.beta'
- }
- production{
- applicationId 'com.yifeng.mdstudysamples'
- }
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- debug {
- applicationIdSuffix '.debug'
- }
- }
- }
我们配置了 beta 和 production 两种 productFlavors,release 和 debug 两种 buildTypes。所以,对应的 Build Variants 就有四种,分别为:betaDebug、betaRelease、productionDebug 和 productRelease。可以在 Build Variants 窗口查看并选择对应的构建类型运行应用:
注意:前面提到,buildTypes 通过添加后缀的方式修改 applicationId(包名)的,换句话说,就是在 productFlavors 的基础上修改包名的。所以,在上面这个例子中,betaRelease 构建类型打包出的 apk 文件的包名是:com.yifeng.mdstudysamples.beta.debug。
五、实现方式
通过上面这些介绍,基本上大家能够知道在 Android 上如何实现 app 的环境分离了。我们可以选择使用 productFlavors 和 buildTypes 这两种方式在同一个设备上来安装同一个应用的不同版本。他们道理上是一样的,只是相比之下,使用 buildTypes 不用新建 productFlavors,更为方便。这里我就 buildTypes 为例简单描述一下环境分离的实现。
1. 对于一个默认 productFlavors 和 buildTypes 配置的项目,我们修改 debug 配置的 applicationIdSuffix 属性,设为 ".debug"(名字可以随意设置),release 版本不用变动。
- android {
- ...
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- debug {
- applicationIdSuffix '.debug'
- }
- }
- }
有了这一步,已经能够将 debug 版本和 release 的 apk 安装在同一个设备上了。还可以做到更好,比如修改 debug 版本的桌面图标、应用名称等,便于区分。
2. 我们在 src 目录下新建一个 debug 目录,将 main 目录下的 res 目录复制一份到 debug 目录下,修改各个分辨率下的桌面 Icon 和 strings.xml 文件中的应用名称,加个 debug 标识。目录结构如图所示:
在构建打包时,debug 目录下的 res 资源采用叠加的方式合并到 main 里面去,并替换相同的内容,而这个例子只需要修改桌面 Icon 和应用名称,所以这里我只复制了 res 目录下的相关文件,其他文件并未复制。
3. 修改代码里的服务器接口地址,选择对应的 Build Variants 类型,运行即可。其实也可以在 debug 和 main 目录下的 string.xml 资源文件中定义服务器地址,然后在程序的入口处赋值给代码里的全局静态变量。
总结
以上就是这篇文章的全部内容了,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。
来源: http://www.phperz.com/article/17/0318/297909.html