很多时候我们会有这样一个需求,版本迭代中当前版本的开发和改bug工作已经基本完毕,进入后台api切换到线上环境的测试阶段,这时候我们需要修改app代码的情况已经不多,后台api的童鞋可能需要切换不同的环境做调试,而安装不同环境app的测试设备数量是有限的,所以最好能在一部测试设备上安装几个连接不同环境的apk,而且是同一个应用程序,只是包名不同。
进入正题。首先在module的build.gradle中配置几个productFlavor:
android{
....
productFlavors {
releaseOnline {
buildConfigField "int", "USE_SERVER", "0"
}
manualConfig {
buildConfigField "int", "USE_SERVER", "0"
}
debug239 {
applicationIdSuffix ".debug239" //定义不同包名,这一个productFlavor安装后的包名是com.fenlibao.fenlibao.debug239
buildConfigField "int", "USE_SERVER", "1" //自定义一个全局常量,用来读取不同配置
}
debug236 {
applicationIdSuffix ".debug236"
buildConfigField "int", "USE_SERVER", "2"
}
debugtem {
applicationIdSuffix ".debugtem"
buildConfigField "int", "USE_SERVER", "3"
}
}
....
}
其中定义applicationIdSuffix的作用是加后缀区分包名,没有指定applicationIdSuffix的则沿用原来的包名com.fenlibao.fenlibao。USE_SERVER的作用是为指定连接不同的服务器(环境)。定义了productFlavors之后就可以在Studio编辑界面的左侧找到Build Variants面板,指定当前app module的build variant(productFlavor + buildType),每一个productFlavor编译后对USE_SERVER单独赋值。
然后为了区分不同的环境,在手机上能够一眼就辨认出哪一个包连接的是哪一个环境,还需要改一下应用名,例如连接236测试环境的,就把应用名命名为debug236,这个又怎么实现呢?
在src目录下创建目录debug236,再在debug236下创建目录res,然后在res下创建Android resource directory
Source set选择debug236,目录名values
在里面创建appname.xml,写上对应的应用名
debug236
同时,我还希望不同的productFlavor打出来的包以相应的productFlavor作为后缀命名,那么在build.gradle里面可以这样配置:
android{
....
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
if(variant.buildType.name.equals('release')){
def fileName = "fenlibao_V${defaultConfig.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
if(variant.buildType.name.equals('debug')){ //此处为debug版本配置不同的命名
def fileName = "fenlibao_V${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
....
}
最后在读取连接服务器的配置时,根据当前productFlavor连接不同的服务器地址:
//0.239_测试环境;1.236_new测试环境;2.236_测试环境;3.212_测试环境;4.准现网;5.生产环境;
private static final int SERVER = getServer();
private static int getServer(){
if("release".equals(BuildConfig.BUILD_TYPE)){//release版本,连接线上环境
return 5;
}
if(BuildConfig.USE_SERVER == 1){//连接239
return 0;
}else if(BuildConfig.USE_SERVER == 2){//连接236
return 1;
}else if(BuildConfig.USE_SERVER == 3){//连接准现网
return 4;
}
return 1;
}
展示一下成果: