Android Studio 自从升级到3.0之后,gradle的玩法也随之变得更加丰富起来,今天就来讲讲有关flavorDimensions(官网翻译过来是风味维度)的配置。
Android Studio3.0之前,进行多模块依赖开发的情况下,项目是正常运行的,然而把studio升级到3.0之后,原本的项目就出现了问题,具体问题如下:
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
项目是没问题的,那么就应该是配置上出了问题,但这又是什么鬼?
经过了一番的折腾,终于明白了是怎么回事。直译过来的话就是所有的风味现在必须属于一个已命名的风味维度。官网提供的解决方式是:
// 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,定义风味维度(也就是命名风味维度)。
然后在产品风味中指定所属的风味维度。
好了,以上只是针对出现的问题进行解决,接下来就是针对flavorDimensions进行一些验证。
多维度理解
其实这涉及到了版本差异化打包的内容,如果说3.0以前的版本差异化打包更多的是为了厂商定制的,那么3.0以后的版本差异化打包就是在厂商的基础之上加入了机型,渠道等一些参数,变成了多个维度的产品。
也就是说之前的一个产品只有一个参数进行描述的话,现在就可以为其增加多个参数进行配置,比如A厂商的A渠道的A机型、A厂商的B渠道的C机型等,维度越多,产品的样式越发丰富。
好了,理论说完,接下来就是进行通俗易懂的一些示例了,只有实践才能让自己检验到真理。
新建项目,然后在app/build.gradle文件里配置两个风味维度(“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"
}
然后进行产品的多维度配置(完整配置在文章下面):
productFlavors{
//随便命名,建议根据该维度的具体信息进行命名
companyA{
dimension "company"
}
companyB{
dimension "company"
}
channelA{
dimension "channel"
}
channelB{
dimension "channel"
}
}
配置完之后进行gradle构建,如果用Terminal命令直接构建打包的话,用如下命令:
//windows
gradlew :app:assembleRelease
//mac
./gradlew :app:assembleRelease
也可以直接用studio进行打包,在最右边有个Gradle,里面有很多task,直接选择assembleRelease,如图:
打包构建之后就会出现多个维度的产品,对应如下,如图:
可以理解为总共有两个维度,公司(company)和渠道(channel),这里公司的维度排前面(排序先后有要求,下面会讲到),所以所有的产品就是,A公司的A渠道产品,A公司的B渠道产品,B公司的A渠道产品,B公司的B渠道产品。
可见,增加维度之后,版本差异化的内容就更为丰富了。
上面说了,维度的定义先后是有要求的,不可随便,下面为了验证这个说法进行了一项测试,我们在productFlavors里给每一个特点产品定义一个常量,常量的值就是该特点产品的名字。如下:
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的常量时,需要把双引号也加进去。
然后进行跟刚才一样的构建,对比几个风味维度的BuildConfig文件里的这个FLAVOR_NAME常量,会发现总是显示第一维度company的值,而第二维度channel的值并不存在,所以当产生多维度的产品时,定义的一些常量总是以第一维度的配置为准。结果如下:
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'
}