在安卓项目中,经常会碰到这样的需求,我们需要在同一台手机上装上同一个App,App内部逻辑一摸一样,但可能对接的后端的接口以及数据库不一致,从而产生多个代码环境,比如测试化境,开发环境,生产环境等等。对于此种需求,我们要面临的问题有以下几个:
1.我们如何写一个配置文件,然后再按需求注释掉不需要的代码,而留下需要的代码。
2.我们如何将配置文件的某些配置被AndroidManifest文件引用,以便在切换环境后产生不同配置
3.我们如何将配置文件的某些配置被代码应用,以便在切换环境后产生不同数据
针对以上问题,我查询了一些资料,在此做个小总结,同时也写了一个非常简易的demo,希望为万能的网友们提供些许参考。
1.写配置文件:我们可以在项目的根目录创建一个“config.gradle”文件,内部写上你需要切换的配置,如下
ext {
android = [
compileSdkVersion: 28,
buildToolsVersion: "28.0.3",
minSdkVersion : 19,
targetSdkVersion : 26,
versionCode : 1,
versionName : "1.0.0",
//Pro环境
// appLabel : "一键切换PRO",
// applicationId : "com.test.demo.quicklychange.pro",
// envName : "Pro",
// envNumber : "310"
//Test环境
// appLabel : "一键切换Test",
// applicationId : "com.test.demo.quicklychange.test",
// envName : "Test",
// envNumber : "320"
//UAT环境
appLabel : "一键切换UAT",
applicationId : "com.test.demo.quicklychange.uat",
envName : "UAT",
envNumber : "330"
]
dependencies = [
"appcompat-v7" : "com.android.support:appcompat-v7:28.0.0",
"junit" : "junit:junit:4.12",
"runner" : "com.android.support.test:runner:1.0.2",
"espresso-core": "com.android.support.test.espresso:espresso-core:3.0.2"
]
}
2.让工程根目类的build.gradle引用此配置文件,如下,引用成功后就可以实现条条道路通罗马了
apply from: "config.gradle"
buildscript {
repositories {
google()
jcenter()
}
3.在app的build.gradle中引用rootProject的配置参数,同时开放出口:
1)给AndroidManifest文件引用
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
applicationId rootProject.ext.android.applicationId
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
/**
* 此处配置数据用于AndroidManifest文件调用
*/
manifestPlaceholders = [
APP_LABEL: rootProject.ext.android.appLabel,
PAK_NAME : rootProject.ext.android.applicationId
]
}
2)给代码引用
buildTypes {
/**
* 此处配置数据用于代码中调用
*/
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "int", "envNumber", rootProject.ext.android.envNumber
buildConfigField "String", "envName", "\"" + rootProject.ext.android.envName + "\""
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "int", "envNumber", rootProject.ext.android.envNumber
buildConfigField "String", "envName", "\"" + rootProject.ext.android.envName + "\""
}
}
4.在AndroidManifest文件中使用被引用的配置,我们将通过meta-data的方式实现
1)改变app的名称
2)改变Provider
5.在代码中使用被引用的配置,我们将通过调用BuildConfig这个java类实现
private void initData() {
//此处数据实际来源于配置文件
mTvMainEnvName.setText("这是" + BuildConfig.envName + "环境");
mTvMainEnvNumber.setText("环境代号" + BuildConfig.envNumber);
}
以上,是我总结的几个关键流程点,碰到的问题有:
1)我定义的“envNumber”的配置参数在配置文件中是一个String,而在代码中使用时是一个int
2)我定义的“envName”的配置参数在配置文件中是一个String,在代码中也是一个String,需要在引用的时候头尾加上 "\"",像这样:
buildConfigField "String", "envName", "\"" + rootProject.ext.android.envName + "\""
最后,将demo的地址公布一下,详细的过程可查阅demo
https://github.com/blood1093/QuicklyChange