productFlavors是在gradle中配置多渠道的打包的工具。使用productFlavors区分不同的产品,定义不同的逻辑,使构建部分有差异的Android项目更加方便。
什么是渠道包呢?渠道包就是为不同的应用市场打的apk包。一般的做法是在发布的apk包的清单文件中的某个meta-data标签下,配置相应value,这个标签的作用就是用来区分是哪个市场的,比如你发布到360.这个值就是你就可以配置成360,豌豆荚就可以配置成wandoujia,这么配置的作用是用来做统计用的,比如使用友盟统计,它就可以统计用户从哪个平台下载了你们的app,从而更好的掌握用户的操作习惯。所以,如果app没有统计功能的需求,你只需要打一个同样的包,直接发布到各个平台即可,根本不用关心什么渠道。
设置productFlavors的步骤如下:
1.创建不同的产品
在app:
级别下的build.gradle文件中,如下图1,加入productFlavors,并创建不同的产品,并为不同的产品分配专有属性。如:在productFlavors
下创建产品product
与temp

图1
android {
...
flavorDimensions "prod"
productFlavors {
//新建产品product
product {
//程序包名,可以编译出不包名的apk
applicationId "study.ung.differentsource.product"
//不同渠道号
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]
//versionName
versionName "1.0.0"
//versionCode
versionCode 1
dimension "prod"
}
//新建产品temp
temp {
//程序包名,可以编译出不包名的apk
applicationId "study.ung.differentsource.temp"
//不同渠道号
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
//versionName
versionName "2.1.1"
//versionCode
versionCode 2
dimension "prod"
}
}
}注意:所有的flavors都必须同属于某一个范围,所以要在productFlavors外面定义:
flavorDimensions "自定义名称" ,如flavorDimensions "prod",
然后在每个flavors中都加入:dimension "prod"让其属于prod这个范围。
这是插件3.0.0的一个新的依赖机制,它会在使用库时自动匹配变体。
还可以通过以下方法指定渠道:
productFlavors {
wandoujia {}
baidu {}
c360 {}
uc {}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
...
}
2.设置不同的代码引用
切换到project视窗,先在src目录下,创建对应的文件夹,如本文的例子,就是要创建product和temp文件夹,然后在它们里面创建与main文件夹下一模一样的目录结构。对于资源文件夹res,则建立product/res、temp/res。如下图:

3.在app:级别下的build.gradle文件中设置不同产品的sourceSets,即指定不同产品的源码文件所在的路径,如下所示:
android {
...
sourceSets {
//不同产品不同的文件
product {
java.srcDirs = ['src/product/java']
}
temp {
java.srcDirs = ['src/temp/java']
}
}
flavorDimensions "prod"
productFlavors {
...
}
}
4.在app:级别下的build.gradle文件中设置不同产品引入的不同的依赖包
旧Gradle版本的方式:产品名Compile 'xxx.xxx.xx'
新Gradle版本的方式:产品名Implementation 'xxx.xxx.xx'
如果引入的就依赖包没有产品名作为前缀,则为main所用,即公共的。
apply plugin: 'com.android.application'
android {
...
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
...
productImplementation 'com.android.support:design:27.1.1'
tempImplementation 'com.alibaba:fastjson:1.2.47'
}
5.最后,在Android Studio左下角的Build Variants菜单中可以看到如下界面:

如果还像下面那样指定了其他渠道:
productFlavors {
wandoujia {}
baidu {}
c360 {}
uc {}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
...
}还可以见到其他渠道版本,如下所示:

我们在run一个项目时,在Build Variants视窗里选相应的Build Variant,它就会将相应的差异部分和main合并在一起编译,最终运行成一个项目。
注意:指定了渠道,就要像product、temp那样定义出各个渠道的产品,否则在打包时列表中会没有相应的渠道版本可以选择。
总结:我们把相同部分放在main下,有差异的部分就放productFlavors声明的相应的项目里,运行时,根据Build Variant的选择,将相应项目的差异部分合并到main里来一起编译。
应用举例:在实际中,我们有生产环境、测试环境、灰度环境,它们使用了不同的服务器、数据库,我们使用productFlavors创建一些产品并将这些服务器、数据库信息,存到这些产品的某个文件里,比如说在product/java/com.wong/product/AppConfig配置正式生产环境的信息,在temp/java/com.wong/product/AppConfig配置正式测试环境的信息。这样我们就随意切换环境了。





