Android 多渠道打包配置
一般我們開發的環境分為:debug 和 release,但是你想再分內測1環境、內測2環境等等怎麼辦呢?
這就需要依賴強大的gradle 來配置了。
相關的配置也可以參考谷歌官方文件。
配置構建型別buildTypes
*名詞解析:*我們通常會分不同的編譯環境進行打包,比如有debug、release、beta等環境引數,像這種我們就稱之為buildTypes.
您可以在模組級build.gradle
檔案的android {}
程式碼塊內部建立和配置構建型別。當您建立新模組時,Android Studio 會自動為您建立除錯和釋出這兩種構建型別。儘管除錯構建型別不會出現在構建配置檔案中,Android Studio 會將其配置為debuggable true
。這樣,您可以在安全的 Android 裝置上除錯應用並使用通用除錯金鑰庫配置 APK 簽署。
如果您希望新增或更改特定設定,您可以將除錯構建型別新增到您的配置中。以下示例為除錯構建型別指定了applicationIdSuffix
,並配置了一個使用除錯構建型別中的設定進行初始化的jnidebug
構建型別。
applicationIdSuffix:
欄位表示,在不改變你預設的程式ID(包名)的情況下,為其新增字尾。比如你的包名是com.rae.app
,但你想區分測試包和正式包的情況,這個時候將applicationIdSuffix
設定為.debug
,那麼你的應用程式對應的包名就變成了com.rae.app.debug
android { ... defaultConfig {...} buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" } /** * The 'initWith' property allows you to copy configurations from other build types, * so you don't have to configure one from the beginning. You can then configure * just the settings you want to change. The following line initializes * 'jnidebug' using the debug build type, and changes only the * applicationIdSuffix and versionNameSuffix settings. */ jnidebug { // This copies the debuggable attribute and debug signing configurations. initWith debug applicationIdSuffix ".jnidebug" jniDebuggable true } } } 複製程式碼
構建源集
名詞解析:
通常原始碼是放在src/main
資料夾下的,但你想可以根據不同的構建型別(比如debug、release)區分不同的原始檔,這樣對應建立的資料夾就是一個不同的構建源。打個比方,debug的構建源為src/debug
,release的構建源為src/release
,而在src/main
定義的為公共資源,最後在構建的時候會進行合併操作。
更多參考官網文件。
Android Studio 按邏輯關係將每個模組的原始碼和資源分組為源集。模組的 main/ 源集包括其所有構建變體共用的程式碼和資源。其他源集目錄為可選項,在您配置新的構建變體時,Android Studio 不會自動為您建立這些目錄。不過,建立類似於 main/ 的源集有助於讓 Gradle 只應在構建特定應用版本時使用的檔案和資源井然有序:
構建源的命名規則如下:
productFlavor
表示渠道包,可以看下面的多渠道打包
-
src/main/
此源集包括所有構建變體共用的程式碼和資源。 -
src/
<buildType>
/ 建立此源集可加入特定構建型別專用的程式碼和資源。示例:src/jnidebug
-
src/
<productFlavor>
/ 建立此源集可加入特定產品風味專用的程式碼和資源。比如百度渠道包:src/baidu
-
src/
<productFlavorBuildType>
/ 建立此源集可加入特定構建變體專用的程式碼和資源。
例如,要生成應用的“完全除錯”版本,構建系統需要合併來自以下源集的程式碼、設定和資源。比如:百度的開發環境包:src/baiduDebug
構建型別的依賴配置
很多時候我們會把sdk或者api介面單獨做成一個庫,一般會有生產環境和測試環境之分,但在依賴的時候往往我們會像這樣去引用:compile project(':sdk')
,這樣依賴的環境就是release
,在開發除錯的時候測試環境的時候就不行了。我們得換另外一種方式:
<buildType>
Compile project()
這樣會根據不同的構建型別去依賴不同的包,比如我們測試環境的依賴包:debugCompile project(':sdk')
,再比如上面的jnidebug
:jnidebugCompile project(':sdk')
那麼問題來了,我當前的構建型別怎麼對應到其他的module
去呢?比如你的app要依賴sdk module 的debug 環境,那麼你可以這麼做:
configuration
:目標module
的<buildType>
,比如你sdk 中<buildType>
的debug
構建型別
debugCompile project(path: ':sdk', configuration: 'debug')
綜合示例
1、先看app這邊的build.gradle
配置:
apply plugin: 'com.android.application' android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix '.debug' minifyEnabled false } // 自定義的構建型別,名字隨便取,一定要有意義 raedebug { initWith debug applicationIdSuffix '.raedebug' } } } dependencies { // 生成環境依賴 releaseCompile project(path: ':sdk', configuration: 'release') // 測試環境依賴 debugCompile project(path: ':sdk', configuration: 'debug') // 自定義構建型別依賴 raedebugCompile project(path: ':sdk', configuration: 'uutest') } 複製程式碼
2、sdk module的build.gradle
配置:
apply plugin: 'com.android.library' android { buildTypes { debug { debuggable true minifyEnabled false } release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } // 注意這裡,跟第一點的 raedebugCompile project的configuration要匹配。 uutest { initWith debug } } } 複製程式碼
多渠道打包productFlavors
先看看build.gradle
配置你就懂了
android{ // 渠道包定義,預設定義的名稱就是渠道名稱 productFlavors { dev {} // 測試 baidu {}// 百度手機助手 yinyongbao {}// 應用寶 m360 {}// 360手機助手 pp {}// PP助手 anzhi{}// 安智市場 xiaomi {}// 小米商店 letv {}// 樂視商店 huawei {}// 華為商店 lenovomm {}// 聯想樂商店 other {}// 其他市場 official{}// 官方版本 } // 批量渠道包值替換 productFlavors.all { flavor -> // 友盟、極光推送渠道包, UMENG_CHANNEL 是根據你AndroidManifest.xml來配置的,請看下面。 flavor.manifestPlaceholders = [UMENG_CHANNEL: name, JPUSH_CHANNEL: name] } } 複製程式碼
AndroidManifest.xml
配置:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rae.demo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <!--變數採用${變數名}這樣來替換,不僅限與<meta-data /> 標籤,任何你想替換的都行。--> <meta-data android:name="UMENG_APPKEY" android:value="${UMENG_APPKEY}"/> <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL}"/> <!--${變數隨變換}--> <activity android:name=".DemoActivity" android:label="${變數隨變換}"/> </application> </manifest> 複製程式碼
sync gradle之後看看gradle projects 面板列表就多出了好到渠道的任務了,Build Variants 面板也相對應多了這些構建型別。
APK輸出配置
在結合到多渠道打包後,運營的那邊希望我們給的渠道包是這種格式的app-{版本號}-{渠道名稱}.apk
,那我們來看看怎麼來滿足這個多渠道打包輸出apk檔名修改的。
android{ // 輸出檔案配置 applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { def dirName = outputFile.parent // 輸出資料夾所在的位置 // 檔名修改 def fileName = "app-${output.processResources.variantName}-${defaultConfig.versionName}-${variant.flavorName}.apk" // 比如不想這麼麻煩,直接在後面加上版本號也行: // def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk") output.outputFile = new File(dirName, fileName) } } } } 複製程式碼
上面介紹的多渠道打包是採用gralde預設的配置,但有個弊端是每個渠道包都會重新編譯一次,編譯速度慢。對大量的多渠道打包推薦用美團的walle
,專案地址:github.com/Meituan-Dia…