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文件錯誤)