在我們做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