Android Studio
自從升級到 3.0
之后握恳,gradle
的玩法也隨之變得更加豐富起來,今天就來講講有關(guān) flavorDimensions
(官網(wǎng)翻譯過來是風(fēng)味維度)的配置捺僻。
Android Studio3.0
之前乡洼,進行多模塊依賴開發(fā)的情況下,項目是正常運行的匕坯,然而把 studio
升級到 3.0
之后束昵,原本的項目就出現(xiàn)了問題,具體問題如下:
Error:All flavors must now belong to a named flavor dimension.Learn more at
https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
項目是沒問題的葛峻,那么就應(yīng)該是配置上出了問題锹雏,但這又是什么鬼?
經(jīng)過了一番的折騰术奖,終于明白了是怎么回事礁遵。直譯過來的話就是所有的風(fēng)味現(xiàn)在必須屬于一個已命名的風(fēng)味維度轻绞。官網(wǎng)提供的解決方式是:
// Specifies a flavor dimension.
flavorDimensions "color"
productFlavors {
red {
// Assigns this product flavor to the 'color' flavor dimension.
// This step is optional if you are using only one dimension.
dimension "color"
...
}
blue {
dimension "color"
...
}
}
在 defaultConfig
里面加入 flavorDimensions
,定義風(fēng)味維度(也就是命名風(fēng)味維度)佣耐。
然后在產(chǎn)品風(fēng)味中指定所屬的風(fēng)味維度政勃。
好了,以上只是針對出現(xiàn)的問題進行解決兼砖,接下來就是針對 flavorDimensions
進行一些驗證奸远。
多維度理解
其實這涉及到了版本差異化打包的內(nèi)容,如果說 3.0
以前的版本差異化打包更多的是為了廠商定制的讽挟,那么 3.0
以后的版本差異化打包就是在廠商的基礎(chǔ)之上加入了機型懒叛,渠道等一些參數(shù),變成了多個維度的產(chǎn)品耽梅。
也就是說之前的一個產(chǎn)品只有一個參數(shù)進行描述的話薛窥,現(xiàn)在就可以為其增加多個參數(shù)進行配置,比如 A
廠商的 A
渠道的A機型眼姐、 A
廠商的 B
渠道的 C
機型等拆檬,維度越多,產(chǎn)品的樣式越發(fā)豐富妥凳。
好了竟贯,理論說完,接下來就是進行通俗易懂的一些示例了逝钥,只有實踐才能讓自己檢驗到真理屑那。
新建項目,然后在 app/build.gradle
文件里配置兩個風(fēng)味維度(“company”艘款,“channel”)
持际,如下:
defaultConfig {
applicationId "com.voctex.flavorsapp"
minSdkVersion 18
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
flavorDimensions "company","channel"
}
然后進行產(chǎn)品的多維度配置(完整配置在文章下面):
productFlavors{
//隨便命名,建議根據(jù)該維度的具體信息進行命名
companyA{
dimension "company"
}
companyB{
dimension "company"
}
channelA{
dimension "channel"
}
channelB{
dimension "channel"
}
}
配置完之后進行 gradle
構(gòu)建哗咆,如果用 Terminal
命令直接構(gòu)建打包的話蜘欲,用如下命令:
//windows
gradlew :app:assembleRelease
//mac
./gradlew :app:assembleRelease
也可以直接用 studio
進行打包,在最右邊有個 Gradle
晌柬,里面有很多 task
姥份,直接選擇 assembleRelease
,如圖:
打包構(gòu)建之后就會出現(xiàn)多個維度的產(chǎn)品年碘,對應(yīng)如下澈歉,如圖:
可以理解為總共有兩個維度,公司(company)
和渠道(channel)
屿衅,這里公司的維度排前面(排序先后有要求埃难,下面會講到),所以所有的產(chǎn)品就是,A
公司的 A
渠道產(chǎn)品涡尘,A
公司的 B
渠道產(chǎn)品忍弛,B
公司的 A
渠道產(chǎn)品,B
公司的 B
渠道產(chǎn)品考抄。
可見剧罩,增加維度之后,版本差異化的內(nèi)容就更為豐富了座泳。
上面說了,維度的定義先后是有要求的幕与,不可隨便挑势,下面為了驗證這個說法進行了一項測試,我們在 productFlavors
里給每一個特點產(chǎn)品定義一個常量啦鸣,常量的值就是該特點產(chǎn)品的名字潮饱。如下:
productFlavors{
companyA{
dimension "company"
buildConfigField "String","FLAVOR_NAME","\"companyA\""
}
companyB{
dimension "company"
buildConfigField "String","FLAVOR_NAME","\"companyB\""
}
channelA{
dimension "channel"
buildConfigField "String","FLAVOR_NAME","\"channelA\""
}
channelB{
dimension "channel"
buildConfigField "String","FLAVOR_NAME","\"channelB\""
}
}
這里有個要注意的點就是在 BuildConfig
定義 String
的常量時,需要把雙引號也加進去诫给。
然后進行跟剛才一樣的構(gòu)建香拉,對比幾個風(fēng)味維度的 BuildConfig
文件里的這個 FLAVOR_NAME
常量,會發(fā)現(xiàn)總是顯示第一維度 company
的值中狂,而第二維度 channel
的值并不存在凫碌,所以當產(chǎn)生多維度的產(chǎn)品時,定義的一些常量總是以第一維度的配置為準胃榕。結(jié)果如下:
BuildConfig.java
文件生成后會在app/build/generated/source/buildConfig/companyAChannelA/release/com/voctex/flavorsapp/BuildConfig.java
-------------------------------------------圖片分割線------------------------------------------
-------------------------------------------圖片分割線------------------------------------------
-------------------------------------------圖片分割線------------------------------------------
實驗證明盛险,當你在各個維度各自定義了同一個常量的值,總是以第一維度的為準勋又,只有第一維度的定義或者說是修改才是有效的苦掘。
對了,忘記加上完整的配置信息楔壤,重新貼上:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.voctex.flavorsapp"
minSdkVersion 18
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
flavorDimensions "company","channel"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors{
companyA{
dimension "company"
buildConfigField "String","FLAVOR_NAME","\"companyA\""
}
companyB{
dimension "company"
buildConfigField "String","FLAVOR_NAME","\"companyB\""
}
channelA{
dimension "channel"
buildConfigField "String","FLAVOR_NAME","\"channelA\""
}
channelB{
dimension "channel"
buildConfigField "String","FLAVOR_NAME","\"channelB\""
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
// testImplementation 'junit:junit:4.12'
// androidTestImplementation 'com.android.support.test:runner:1.0.2'
// androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
因此鹤啡,在項目中可以通過如下方式分別實現(xiàn)代碼邏輯(以下通過FLAVOR變量控制,也可使用或搭配其他變量):
比如本地工具類 Utils.java 中定義了對應(yīng)的字符串變量蹲嚣,對應(yīng) BuildConfig.java中生成的值:
...
public static final String COMPANYA_CHANNELA= "companyAchannelA";
public static final String COMPANYA_CHANNELB= "companyAchannelB";
...
然后其它功能類的代碼中就可以通過判斷當前的配置變量實現(xiàn)對應(yīng)型號的邏輯:
...
if (Utils.COMPANYA_CHANNELA.equals(BuildConfig.FLAVOR)) {
//公司 A 產(chǎn)品 A 想實現(xiàn)的代碼邏輯
} else if (Utils.COMPANYA_CHANNELB.equals(BuildConfig.FLAVOR)) {
//公司 A 產(chǎn)品 B 想實現(xiàn)的代碼邏輯
} else {
//默認配置平臺想實現(xiàn)的代碼邏輯
}
...