productFlavor
productFlavors直译过来就是特色的产品,所以他的主要作用就是让你同一套代码生产出不同的特色产品
productFlavors是build.gradle里面配置的,主要就是通过gradle打包时可以有多种配置供选择,类似buildTypes,并且可以和buildTypes共存
1.应用场景
- 创建不同的产品(staging,production)(各种手机品牌)
- 创建不同的产品并为不同产品分配专有属性
- 设置不同代码引用
- 先在src目录下简历对应的文件夹比如java代码则建立productjavares文件夹则建立productres
- 建立包名建立Java类文件
- 在app-level下的gradle文件中设置sourceSets
- 设置不同的产品引入不同的包
2.组合
//使用flavorDimensions属性来创建一个“模式”风味维度,维度来区分不同的类型,然后两个类型之间组合
//“dev”指的是编译出来是什么环境的apk
//“app”指的是app1和app2
//(app的配置+dev的环境一起编译)
flavorDimensions "dev","app"`
productFlavors{
//app2产品,注意(这边的产品名字字母不能大写)
B{
dimension "app"
applicationIdSuffix "com.wmj.b"
versionCode 1
versionName "1.0.0"
}
//app1产品,注意(这边的产品名字字母不能大写)
A{
dimension "app"
applicationId "com.wmj.a"
versionCode 1
versionName "1.0.0"
}
//线上环境
product{
dimension "dev"
}
//测试环境
staging{
dimension "dev"
}
//预发环境
deving{
dimension "dev"
}
}
3.分配资源(关键)
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/java']
aidl.srcDirs = ['src/main/java']
renderscript.srcDirs = ['src/main/java']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
jniLibs.srcDirs = ['libs']
}
staging.java.srcDirs = ['src/local/java']
staging.res.srcDirs = ['src/local/res']
production.java.srcDirs = ['src/us/java']
production.res.srcDirs = ['src/us/res']
把main下的资源,列如Constant.java文件剪切+粘贴到”src/staging/java/com/xx/lib/Constant.java”和”src/production/java/com/xx/lib/Constant.java”的对应包下(注意千万不能保留main下的Constant.java文件,且两个包名路径必须是一样的),并且相应修改Constant.java里面的服务器地址,同理相关res文件也是一样
步骤分析:在Gradle进行构建时,它会现在main目录下寻找所需的.java文件,如果找不到,就会在构建时选择的渠道对应源码目录下寻找,如果此时main和渠道源码目录都有同一个.java文件,就会报“duplicate class(重复类)”错误。因此,应该删除main的原文件。
4.动态变量
declare in the gradle file:
productFlavors{
xiaomi{
buildConfigField "int", "APP_TYPE", "1"
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi",APP_NAME:"xiaomi版"]
}
huawei{
buildConfigField "int", "APP_TYPE", "2"
manifestPlaceholders = [CHANNEL_VALUE: "xiaomi",APP_NAME:"xiaomi版"]
}
}
read in the java code:
int type = BuildConfig.APP_TYPE;
read in the Mainifest.xml:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="${APP_NAME}"
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>
<meta-data android:name="CHANNEL" android:value="${CHANNEL_VALUE}" />
</application>
5.生成apk命名规则
// rename the apk with the version name(https://blog.csdn.net/hzypf/article/details/80251310)
applicationVariants.all { variant ->
variant.outputs.all { output ->
def date, buildName
//get productFlavors's name
variant.productFlavors.each { product ->
buildName = product.name
}
if (variant.buildType.name == "release") {
date = new Date().format("yyyyMMdd_HH_mm_ss", TimeZone.getTimeZone("GMT+8"))
outputFileName = "TigerBox_${variant.buildType.name}_${variant.versionName}_${variant.versionCode}_${buildName}_${date}.apk"
}
if (variant.buildType.name == "debug") {
date = new Date().format("yyyy_MM_dd", TimeZone.getTimeZone("GMT+8"))
outputFileName = "TigerBox_${variant.versionName}_${variant.versionCode}_${buildName}_${date}.apk"
}
}
}
6.不同buildType引用不同第三方库
使用方式:[buildTypeName+Compile] “xxx.xxx.xx”
//不同产品引入不同的包
productCompile "com.android.support:appcompat-v7:26.+"
tempCompile "com.android.support.constraint:constraint-layout:1.0.2"
7.build with productFlavor
切换好以后记得sync一下gradle文件(必须,否则会提示duplicate文件错误)