一.多管道打包applicationVariants{}閉包初級講解
1.需求
多管道打包時,自定義打出的包的名稱。
2.代碼
APP的Gradle檔案
apply plugin: 'com.android.application'
/** ext閉包 在本Gradle中配置 versionCode&versionName 本Gradle的defaultConfig{}包使用 */
ext {
versionInt = 2
versionString = "2.0.0"
releaseTime = releaseTime()
}
android {
compileSdkVersion 28
/** defaultConfig閉包 預設配置 */
defaultConfig {
applicationId "com.wjn.okhttpmvpdemo"
minSdkVersion 19
targetSdkVersion 27
versionCode versionInt
versionName versionString
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
/** signingConfigs閉包 項目簽名配置 */
signingConfigs {
release {
storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
storePassword '123456'
keyAlias 'key0'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
debug {
storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
storePassword '123456'
keyAlias 'key0'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
}
/** buildTypes閉包 項目打包配置 比如是否混淆 是否壓縮 是否支援調式等等 這裡為了區分下面多管道打包Debug包和Release包 在versionName後添加了不同的字尾*/
buildTypes {
release {
minifyEnabled false
debuggable false
multiDexEnabled false
}
debug {
minifyEnabled false
debuggable true
multiDexEnabled false
buildConfigField "String", "MAPID", "\"" + rootProject.ext.android.mapId + "\""
}
}
/** productFlavors閉包 多管道打包 flavorDimensions屬性确定次元 分支&免費付費 */
flavorDimensions "branch", "free_pay"
productFlavors {
red {
dimension "branch"
applicationIdSuffix ".red"
signingConfig signingConfigs.release
}
blue {
dimension "branch"
applicationIdSuffix ".blue"
signingConfig signingConfigs.debug
}
free {
dimension "free_pay"
buildConfigField "boolean", "IS_FREE", "true"
}
pay {
dimension "free_pay"
buildConfigField "boolean", "IS_FREE", "false"
}
}
/** variantFilter閉包 過濾變體 可以設定忽略那個包 比如這裡過濾掉了不在清單中的包*/
variantFilter { variant ->
def needed = variant.name in [
'redFreeRelease',
'redFreeDebug',
'redPayRelease',
'redPayDebug',
'blueFreeRelease',
'blueFreeDebug',
'bluePayRelease',
'bluePayDebug',
]
setIgnore(!needed)
}
/** compileOptions閉包 配置項目使用JDK1.8 */
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
/** applicationVariants閉包 配置項目打包包名 */
android.applicationVariants.all {
variant ->
variant.outputs.all { output ->
//按照規範擷取outputFileName 同時outputFileName字段也是打包的名稱 重要
outputFileName = "OkHttp_" + "${defaultConfig.versionName}_${releaseTime()}" + "_${variant.productFlavors[0].name}.apk"
//更新VersionName
output.setVersionNameOverride(outputFileName)
}
}
/** sourceSets閉包 配置項目檔案 */
sourceSets {
/** 預設 配置項目檔案 */
main {
jniLibs.srcDirs = ['libs']
assets.srcDirs = ['src/main/assets']
}
/** blue包 配置項目檔案 */
blue {
assets.srcDirs = ['../protectFileConfig/assets/blue']
}
/** red包 配置項目檔案 */
red {
assets.srcDirs = ['../protectFileConfig/assets/red']
}
}
}
static def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+8"))
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-v4:27.1.1'
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'
implementation 'io.reactivex:rxjava:1.3.2'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
implementation 'com.github.bumptech.glide:glide:4.4.0'
}
包名規範
OkHttp_+versionName+"_"+時間+"_"+管道名
Java代碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String versionName = getVersionName();
Log.d("MainActivity", "versionName----:" + versionName);
}
/**
* 擷取目前程式版本号名
* android:versionName="2.0"
*/
private String getVersionName() {
PackageManager pm = getPackageManager();
try {
PackageInfo info = pm.getPackageInfo(getPackageName(), 0);
return info.versionName;
} catch (Exception e) {
// 不會發生的異常
return "";
}
}
}
3.驗證
<1> 日志列印
D/MainActivity: versionName----:OkHttp_2.0.0_20170426_blue.apk
<2> 打包截圖
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPn1ENRRUT6NmeOpHOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZwpmLzIzMxATMzQTM5ETNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
二.多管道打包applicationVariants{}閉包進階講解
1.簡介
上述使用applicationVariants{}閉包簡單粗暴的把所有八個包都更新的打出的包的名稱和versionName。那麼如果我們需要判斷呢?比如有些包需要拼字元串,有些包不需要。代碼實作下面講解
2.代碼
apply plugin: 'com.android.application'
/** ext閉包 在本Gradle中配置 versionCode&versionName 本Gradle的defaultConfig{}包使用 */
ext {
versionInt = 2
versionString = "2.0.0"
releaseTime = releaseTime()
}
android {
compileSdkVersion 28
/** defaultConfig閉包 預設配置 */
defaultConfig {
applicationId "com.wjn.okhttpmvpdemo"
minSdkVersion 19
targetSdkVersion 27
versionCode versionInt
versionName versionString
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
/** signingConfigs閉包 項目簽名配置 */
signingConfigs {
release {
storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
storePassword '123456'
keyAlias 'key0'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
debug {
storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
storePassword '123456'
keyAlias 'key0'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
}
/** buildTypes閉包 項目打包配置 比如是否混淆 是否壓縮 是否支援調式等等 這裡為了區分下面多管道打包Debug包和Release包 在versionName後添加了不同的字尾*/
buildTypes {
release {
minifyEnabled false
debuggable false
multiDexEnabled false
}
debug {
minifyEnabled false
debuggable true
multiDexEnabled false
buildConfigField "String", "MAPID", "\"" + rootProject.ext.android.mapId + "\""
}
}
/** productFlavors閉包 多管道打包 flavorDimensions屬性确定次元 分支&免費付費 */
flavorDimensions "branch", "free_pay"
productFlavors {
red {
dimension "branch"
applicationIdSuffix ".red"
signingConfig signingConfigs.release
}
blue {
dimension "branch"
applicationIdSuffix ".blue"
signingConfig signingConfigs.debug
}
free {
dimension "free_pay"
buildConfigField "boolean", "IS_FREE", "true"
}
pay {
dimension "free_pay"
buildConfigField "boolean", "IS_FREE", "false"
}
}
/** variantFilter閉包 過濾變體 可以設定忽略那個包 比如這裡過濾掉了不在清單中的包*/
variantFilter { variant ->
def needed = variant.name in [
'redFreeRelease',
'redFreeDebug',
'redPayRelease',
'redPayDebug',
'blueFreeRelease',
'blueFreeDebug',
'bluePayRelease',
'bluePayDebug',
]
setIgnore(!needed)
}
/** compileOptions閉包 配置項目使用JDK1.8 */
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
/** applicationVariants閉包 配置項目打包包名 */
android.applicationVariants.all {
variant ->
variant.outputs.all { output ->
//擷取分支 red&blue
def appBranch = variant.productFlavors[0].name
//擷取免費付費 free&pay
def free_pay = variant.productFlavors[1].name
//預設的包名
def result = "OkHttp_" + versionString
//操作包名 blue的包 拼後面的字元串 red的包使用預設的字元串不需要拼後面的字元串
if (appBranch == "blue") {
result = result + "_" + free_pay.toUpperCase() + "_" + releaseTime() + ".apk"
} else {
result = result + ".apk"
}
//更新打出的包的名稱
outputFileName = result
//更新VersionName
output.setVersionNameOverride(result)
}
}
/** sourceSets閉包 配置項目檔案 */
sourceSets {
/** 預設 配置項目檔案 */
main {
jniLibs.srcDirs = ['libs']
assets.srcDirs = ['src/main/assets']
}
/** blue包 配置項目檔案 */
blue {
assets.srcDirs = ['../protectFileConfig/assets/blue']
}
/** red包 配置項目檔案 */
red {
assets.srcDirs = ['../protectFileConfig/assets/red']
}
}
}
static def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+8"))
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-v4:27.1.1'
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'
implementation 'io.reactivex:rxjava:1.3.2'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
implementation 'com.github.bumptech.glide:glide:4.4.0'
}
3.驗證
打出八個包截圖
打出八個包清單檔案(順序和上面截圖一緻)
android:versionName="OkHttp_2.0.0_FREE_20170426.apk"
android:versionName="OkHttp_2.0.0_FREE_20170426.apk"
android:versionName="OkHttp_2.0.0_PAY_20170426.apk"
android:versionName="OkHttp_2.0.0_PAY_20170426.apk"
android:versionName="OkHttp_2.0.0.apk"
android:versionName="OkHttp_2.0.0.apk"
android:versionName="OkHttp_2.0.0.apk"
android:versionName="OkHttp_2.0.0.apk"
三.多管道打包 不同包使用不同的依賴
1.需求
多管道打包時,不同的包使用不同的依賴。依賴可能是本地依賴或者本地庫依賴。比如某些第三方的SDK會提供兩個Jar包,Debug包依賴XXXDebugSDK.jar包,Release包依賴XXXReleaseSDK.jar包。
2.代碼
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
/** defaultConfig閉包 預設配置 */
defaultConfig {
applicationId "com.wjn.okhttpmvpdemo"
minSdkVersion 19
targetSdkVersion 27
versionCode rootProject.ext.android.versionInt
versionName rootProject.ext.android.versionString
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
/** signingConfigs閉包 項目簽名配置 */
signingConfigs {
release {
storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
storePassword '123456'
keyAlias 'key0'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
debug {
storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
storePassword '123456'
keyAlias 'key0'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
}
/** buildTypes閉包 項目打包配置 比如是否混淆 是否壓縮 是否支援調式等等 這裡為了區分下面多管道打包Debug包和Release包 在versionName後添加了不同的字尾*/
buildTypes {
release {
minifyEnabled false
debuggable false
multiDexEnabled false
versionNameSuffix '-Release'
}
debug {
minifyEnabled false
debuggable true
multiDexEnabled false
versionNameSuffix '-Debug'
buildConfigField "String", "MAPID", "\"" + rootProject.ext.android.mapId + "\""
}
}
/** productFlavors閉包 多管道打包 flavorDimensions屬性确定次元 分支&免費付費 */
flavorDimensions "branch", "free_pay"
productFlavors {
red {
dimension "branch"
applicationIdSuffix ".red"
signingConfig signingConfigs.release
}
blue {
dimension "branch"
applicationIdSuffix ".blue"
signingConfig signingConfigs.debug
}
free {
dimension "free_pay"
buildConfigField "boolean", "IS_FREE", "true"
}
pay {
dimension "free_pay"
buildConfigField "boolean", "IS_FREE", "false"
}
}
/** variantFilter閉包 過濾變體 可以設定忽略那個包 比如這裡過濾掉了不在清單中的包*/
variantFilter { variant ->
def needed = variant.name in [
'redFreeRelease',
'redFreeDebug',
'redPayRelease',
'redPayDebug',
'blueFreeRelease',
'blueFreeDebug',
'bluePayRelease',
'bluePayDebug',
]
setIgnore(!needed)
}
/** compileOptions閉包 配置項目使用JDK1.8 */
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
android.applicationVariants.all {
variant ->
variant.outputs.all {
outputFileName = "OkHttp_" + "${defaultConfig.versionName}_${releaseTime()}" + "_${variant.productFlavors[0].name}.apk"
}
}
}
static def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+8"))
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-v4:27.1.1'
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'
implementation 'io.reactivex:rxjava:1.3.2'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
implementation 'com.github.bumptech.glide:glide:4.4.0'
//對應上述多管道打出的八個包 有不同的八個依賴
redFreeReleaseImplementation 'com.aaa.bbb.ccc:redFreeRelease:1.1.1'
redFreeDebugImplementation 'com.aaa.bbb.ccc:redFreeDebug:1.1.1'
redPayReleaseImplementation 'com.aaa.bbb.ccc:redPayRelease:1.1.1'
redPayDebugImplementation 'com.aaa.bbb.ccc:redPayDebug:1.1.1'
blueFreeReleaseImplementation 'com.aaa.bbb.ccc:blueFreeRelease:1.1.1'
blueFreeDebugImplementation 'com.aaa.bbb.ccc:blueFreeDebug:1.1.1'
bluePayReleaseImplementation 'com.aaa.bbb.ccc:bluePayRelease:1.1.1'
bluePayDebugImplementation 'com.aaa.bbb.ccc:bluePayDebug:1.1.1'
}