在我们做APP开发时,很多时候会切换不同的网络环境进行调试,有时候还会针对不同的网络环境打多个渠道包让测试人员针对不同开发环境测试,更多的时候是一台手机安装多个不同环境的APP进行测试。而Android Studio很好的理解了我们的诉求,只要通过配置,就能一次性的打包成不同开发环境的多个渠道apk,不仅更换了apk的applicationID,就连APP图标和名称都能更更换。
这里使用 Android Studio 3.5 做演示,AS 3.5以下可能会出现有些gradle命令不支持。
在项目的根目录 gradle.properties 中配置网络请求
这里配置了2个环境url,分别是dev和prod。
env_dev_address = "http://10.20.30.40:8082/"
env_prod_address = "http://11.22.33.44:8083/"
找到项目APP目录下的***build.gradle***,在android节点下添加 productFlavors 节点来创建不同产品的差异信息
- 创建2个产品env_dev,env_prod
productFlavors{
env_dev{
}
env_prod{
}
}
- 考虑到要在同一台手机上安装2个不同环境的APP,为env_dev,env_prod配置不同的applicationId;
productFlavors{
env_dev{
applicationId 'com.gradlesetting.demo.dev'
}
env_prod{
applicationId 'com.gradlesetting.demo.prod'
}
}
3.通过 buildConfigField 添加属性 ENV_API 为env_dev,env_prod配置不同的网络请求地址,这里的 env_dev_address,env_prod_address对应着 gradle.properties 中配置的 url 地址
productFlavors{
env_dev{
applicationId 'com.gradlesetting.demo.dev'
buildConfigField "String" , "ENV_API" , env_dev_address
}
env_prod{
applicationId 'com.gradlesetting.demo.prod'
buildConfigField "String" , "ENV_API" , env_prod_address
}
}
4.为不同渠道 APP 修改不同的APP名称和图标,这里同为 manifestPlaceholders 添加了2个属性 APP_ICON ,APP_NAME,同时需要在 AndroidManifest.xml 的 application 标签中使用这2个属性
productFlavors{
env_dev{
applicationId 'com.gradlesetting.demo.dev'
signingConfig signingConfigs.debug
buildConfigField "String" , "ENV_API" , env_dev_address
manifestPlaceholders = [
APP_ICON : "@mipmap/icon_app_dev",
APP_NAME : "@string/app_name_dev",
]
}
env_prod{
applicationId 'com.gradlesetting.demo.prod'
signingConfig signingConfigs.release
buildConfigField "String" , "ENV_API" , env_prod_address
manifestPlaceholders = [
APP_ICON : "@mipmap/icon_app_prod",
APP_NAME : "@string/app_name_prod",
]
}
}
在 AndroidManifest.xml 的 application 中通过${}表达式使用定义好的 APP_ICON 和 APP_NAME
<application
android:allowBackup="true"
android:icon="${APP_ICON}"
android:label="${APP_NAME}"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
以上配置完成后,将会在 Build Variants 中看到不同产品的配置方案,可以选择需要的产品方案调试
这里分别对应着env_dev,env_prod 的 Debug 和 Release 版本。
以上配置完成后,不同环境渠道包就算配置好了。为了测试配置是否成功,我们将打包不同渠道APK。
在 APP gradle.build -> android -> buildTypes 下通过 buildConfigField 配置常量 LOG_DEBUG,用于在debug包时打印日志,release包不打印日志信息
buildTypes {
debug {
buildConfigField "boolean" , "LOG_DEBUG" , "true"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
buildConfigField "boolean" , "LOG_DEBUG" , "false"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
定义Constant常量,获取 APP 目录下配置的常量 ENV_API,LOG_DEBUG
public class Constants {
public static final String SERVE_URL = BuildConfig.ENV_API;
public static final boolean DEBUG = BuildConfig.LOG_DEBUG;
}
在 APP gradle.build 中配置打包签名文件
signingConfigs{
debug{
storeFile file("./doc/gradle-setting-dev.jks")
storePassword properties.getProperty( 'keystore-password-dev' )
keyAlias "gradle-setting-dev"
keyPassword properties.getProperty( 'keystore-password-dev' )
}
release{
storeFile file("./doc/gradle-setting-prod.jks")
storePassword properties.getProperty( 'keystore-password-prod' )
keyAlias "gradle-setting-prod"
keyPassword properties.getProperty( 'keystore-password-prod' )
}
}
自定义打包输出配置
// 自定义打包输出配置
applicationVariants.all { variant ->
variant.outputs.all { output ->
def apkPostfix=""
if(variant.name.endsWith("Debug")){
apkPostfix="debug"
}else if(variant.name.endsWith("Release")){
apkPostfix="release"
}
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// outputFileName = "${variant.productFlavors[0].applicationId}_${defaultConfig.versionName}_${getDate()}-${apkPostfix}.apk"
outputFileName = "${variant.productFlavors[0].name}_${defaultConfig.versionName}-${apkPostfix}-${getDate()}.apk"
}
}
}
gradlew assemble 打包后,在输出目录下生成2个环境的 debug 和 release 包
如下图,将 debug 包安装在左侧的模拟器,release 包安装在右侧的模拟器
- debug 包获取的常量布尔值 DEBUG = true ;release 包获取的 DEBUG = false
- dev 包映射的 url 是 10.20.30.40:8082,是 gradle.properties 中配置的变量 env_dev_address;prod包映射的 url 是11.22.33.44:8083,是 gradle.properties 中配置的变量 env_prod_address