build.gradle的高階運用,通過Groovy語言合理的編譯打包程式碼,避免資原始檔冗餘
最近做專案,一個專案(一套程式碼)針對多個客戶,要出多個版本,但不同的客戶需求導致專案程式碼有細微的不同,以及應用載入的資源圖片都是不一樣,如果僅僅是程式碼細微差別還好,但是資源圖片載入的都不一樣,這導致apk大包資源圖片冗餘大,這並不是我們所希望的。
android studio 專案裡面的build.gradle我們並不陌生,但是如何高階運用,我相信有許多人和我一樣,一臉懵逼。要利用好build.gradle,必須要對Groovy語言有一點基礎,當然沒有基礎的也可以站在巨人的肩膀上依葫蘆畫瓢,也可以做一些簡單的運用,當要根據自己的的專案以裝逼的方式利用build.gradle配置檔案對專案程式碼合理的編譯打包,避免資原始檔冗餘,那必然會踩很多坑,我就是這麼過來的.哈哈。
當然,我也不是你們心中的巨人,老菜苗一個,所以我也教不了你們Groovy,至於build.gradle的使用也是我花了一天網上學習+瞎折騰的.踩過的坑也是讓自己汗顏.所以決定把我的build.gradle分享出來,作為你們的一個葫蘆,盡情的去畫吧。... ... 自己第一次寫部落格,有點囉嗦了.
通過build.gradle配置檔案可以做很多事情,我下面列舉一些常用的:1.自定義versionCode,versionName的生成規則
2.動態修改Manifest裡面的屬性值,比如AndroidManifest中的icon,label,<meta>標籤值等
3.定製編譯成功後的apk名稱規則
4.新增自定義buildConfig欄位(很有用)
5.自定義編譯任務
6.新增自定義的目錄
7.過濾拓展的自定義目錄,過濾預設的資源圖片等(很有用)
以上是我目前專案所運用到的,後面會有新增,廢話不囉嗦,上程式碼:
----------------------------------------------- 廢話都在程式碼裡面了 ----------------------------------------------------
apply plugin: 'com.android.application'android {
compileSdkVersion 22
buildToolsVersion '25.0.0'
defaultConfig {
applicationId "com.android.tongxunlu"
minSdkVersion 19
targetSdkVersion 22
versionCode buildVersionCode()
versionName buildVersionName()
// 預設的配置
buildConfigField "int" , "oem_type", "-1"
manifestPlaceholders = [label: "通訊錄", icon: "@mipmap/ic_launcher", sharedUserId: "android.uid.system"]
}
//程式在buid的時候,會執行lint檢查,有任何的錯誤或者警告提示,都會終止構建,我們可以將其關掉。
lintOptions {
abortOnError false
ignoreWarnings true
checkReleaseBuilds false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
// debug和release版本的簽名
signingConfigs {
release {
storeFile file("D:/other/mysign/test.jks")
storePassword "12345678"
keyAlias "test"
keyPassword "123456"
}
}
buildTypes {//構建型別,通常有release和debug兩種
release {
signingConfig signingConfigs.release
// minifyEnabled true //開啟混淆
// shrinkResources true;//是否移除無用資原始檔,shrinkResources依賴於minifyEnabled,必須和minifyEnabled一起用
zipAlignEnabled true //是否啟用zipAlign壓縮
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//混淆檔案
}
debug {
signingConfig signingConfigs.release
zipAlignEnabled true //是否啟用zipAlign壓縮
}
// 定製生成apk的名稱
applicationVariants.all { variant ->
// each遍歷variant
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null) {
println "======outputFile.name======" + outputFile.name;
def fileName;
if (outputFile.name.endsWith('release.apk')) {
fileName = "tongxunlu${defaultConfig.versionName}_${variant.productFlavors[0].name}_release.apk";
} else if (outputFile.name.endsWith('debug.apk')) {
fileName = "tongxunlu${defaultConfig.versionName}_${variant.productFlavors[0].name}_debug.apk";
}
output.outputFile = new File(outputFile.name, fileName)
}
}
}
}
// OEM原始裝置製造商{oem_type: 0康冠,1中電數碼,2艾博德,3凱佳達,4富士康,5凌暢,6視美泰,7佳傑,8長虹}
// 程式碼裡面可以針對oem_type進行邏輯分支
// 如果是大的邏輯差異,可以進行src分支,原理同sourceSets中res分支
productFlavors {
// debug
unsigned {// 沒有板卡系統簽名檔案,打這個包
println "======unsigned======"
manifestPlaceholders = [sharedUserId: "com.android.tongxunlu"]
}
// 客戶
KangGuan {// 0康冠
println "======KangGuan======"
manifestPlaceholders = [label: "連屏", icon: "@mipmap/ktc_ic_launcher"]
buildConfigField "int", "oem_type", "0"
}
ZhongDian {// 1中電數碼
println "======ZhongDian======"
manifestPlaceholders = [label: "中電"]
buildConfigField "int", "oem_type", "1"
}
...
}
// 針對不同的客戶,編譯不同的目錄,避免不必要的資源冗餘
sourceSets {// 配置資源集
// 新增目錄,編譯的時候會把所加的目錄編譯進去
// main.res.srcDirs += ['src/main/res-kg']
// main.res.srcDirs += ['src/main/res-zd']
...
// 指定編譯的目錄(其中已經包括了預設的資源)
KangGuan.res.srcDirs = ['src/main/res-kg']
ZhongDian.res.srcDirs = ['src/main/res-zd']
...
}
}
allprojects {
// 注: 某些輸入檔案使用或覆蓋了已過時的 API。
// 注: 有關詳細資訊, 請使用 -Xlint:deprecation 重新編譯。
// 注: 某些輸入檔案使用了未經檢查或不安全的操作。
// 注: 有關詳細資訊, 請使用 -Xlint:unchecked 重新編譯。
// gradle.projectsEvaluated {
// tasks.withType(JavaCompile) {
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
// }
// }
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
compile 'com.mani:ThinDownloadManager:1.2.5'
// compile 'org.nanohttpd:nanohttpd:2.3.0'
compile 'com.google.android.exoplayer:exoplayer:r1.5.9'
compile 'com.android.support:support-v4:22.0.0'
compile files('libs/zxing.jar')
}
/** **********************************************************/// 自定義編譯後的版本號
def buildVersionCode() {
return Integer.parseInt(new Date().format("YYMMddHHmm"))
}
// 自定義編譯後的版本名稱
def buildVersionName() {
def date = new Date();
int ver = Integer.parseInt(date.format("YY")) - 17;// 17年基版本
int si = Integer.parseInt(date.format("MM"));
int on = Integer.parseInt(date.format("dd"));
return "1." + ver + "." + si + "." + on;// 老版本1.開頭
}
/********************** gradle cmd ***************************/
//gradle assembleRelease // 構建productFlavors下所有Variant Release版本
//gradle assembleDebug // 構建productFlavors下所有Variant Debug版本
//gradle assemble[productFlavors.name] // 構建productFlavors下name的Variant Release和Debug版本
//gradle assemble[productFlavors.name]Relase // 構建productFlavors下name的Variant Releaseg版本
//gradle assemble[productFlavors.name]Debug // 構建productFlavors下name的Variant Debug版本
==============================排版什麼的請忽略,下面直接上截圖============================
1.新增的目錄分支,可以針對不同的客戶選擇性編譯目錄檔案,如果指定一個目錄,其他目錄分支沒有指定,那隻會把指定的目錄和預設的目錄一起打包到apk中。
如果res-kg/drawable下的檔名和res/drawable下的檔名同名,打包的時候res-kg/drawable會替換掉res/drawable下的同名檔案,這也正是實現了一個佈局檔案可以根據打包所指定的Flavors不同而讀取的資源也不同.
2.gradle常用命令,使用前需配置好gradle的環境變數。
使用以下命令前最好執行下 gradle clean 命令。
3.通過AS去選擇編譯打包apk
4.通過buildConfigField自定義自動生成的BuildConfig類的成員常量
5.動態修改AndroidManifest.xml裡面的一些值,如icon,label,<meta-data>標籤值等
6.生成的apk名稱,效果圖
毫無排版,看不懂的請見諒,老菜苗覺得關鍵的都毫無保留的貼出來了.O(∩_∩)O哈哈~
老菜苗還有很多Android開發乾貨等有時間後期會分享給大家,謝謝大家!!!