完整配置的Guthub地址:https://github.com/WangFion/mvp-mode
一、什么是 Gradle
??關(guān)于 Gradle 是什么,這里我就不做過(guò)多的贅述了塘装,打開(kāi)度娘一搜一大片顷啼,感興趣的童鞋可以自行學(xué)習(xí)哈锌俱!這里我就簡(jiǎn)單描述一下:
??Gradle 是一個(gè)基于 Apache Ant 和 Apache Maven 概念的項(xiàng)目自動(dòng)化構(gòu)建工具毫胜。它使用一種基于 Groovy 的特定領(lǐng)域語(yǔ)言來(lái)聲明項(xiàng)目設(shè)置晰甚,而不是傳統(tǒng)的 XML降瞳。Gradle 就是工程的管理嘱支,幫我們做了依賴(lài)、打包挣饥、部署除师、發(fā)布、各種渠道的差異管理等工作扔枫。
??這里你只需要己住一點(diǎn):Gradle 是一個(gè)自動(dòng)化構(gòu)建工具汛聚,這就ok了。
二短荐、AS 中的 Gradle 版本
??在 Android Studio 中使用 Gradle 有三個(gè)版本需要注意:AS 版本倚舀、Gradle 插件版本叹哭、Gradle 版本。
1痕貌、AS版本
2风罩、Gradle 插件版本(項(xiàng)目根目錄的 build.gradle)
classpath 'com.android.tools.build:gradle:3.6.3'
3、Gradle 版本(項(xiàng)目根目錄的 /gradle/wrapper/gradle-wrapper.properties)
#Sat May 09 20:18:45 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
1舵稠、其中 AS 的版本和 Gradle 插件的版本是有對(duì)應(yīng)關(guān)系的超升,Gradle 版本根據(jù)項(xiàng)目而定,建議都保持最新版本哺徊。
2室琢、有新版本,如果更新之后編譯不過(guò)并且很難解決落追,亦可保持原編譯通過(guò)版本不變盈滴。
3、個(gè)人建議有新版本就及時(shí)更新轿钠,不要累積很多版本后一次更新巢钓;否則到必須更新的時(shí)候再去更新,相信我你會(huì)痛苦萬(wàn)分的谣膳。
三竿报、Project 的 Gradle 通用配置
??Project 的 Gradle 配置的是項(xiàng)目統(tǒng)一化、公用化的一些信息继谚,目的是為了保證公共的信息在每個(gè) Module 中都是一致的,而每個(gè) Module 只需要去配置自己的一些差異化的信息阵幸。
??Project 的 Gradle 的配置文件是根目錄下面的 build.gradle花履,這里面主要配置遠(yuǎn)程倉(cāng)庫(kù)、插件挚赊、項(xiàng)目版本信息诡壁、公共 lib 等。
1荠割、遠(yuǎn)程倉(cāng)庫(kù)配置
repositories {
// wf-update: 2020/5/9 16:57 添加aliyun鏡像妹卿,優(yōu)化jcenter和google訪(fǎng)問(wèn)
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/google' }
google()
jcenter()
}
往往在我們項(xiàng)目開(kāi)發(fā)的過(guò)程中都會(huì)集成很多 Google 和第三方的開(kāi)源庫(kù),而受?chē)?guó)內(nèi)環(huán)境的影響使用 google() 和 jcenter() 下載這些庫(kù)往往不盡人意蔑鹦,所以這里推薦配置國(guó)內(nèi)的鏡像地址(當(dāng)然不止我上面列舉的這些)夺克,會(huì)有意想不到的效果哦。注意這里需要同時(shí)配置 buildscript 和 allprojects 方法塊嚎朽。
2铺纽、插件配置
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
注意這里的 dependencies 配置的是項(xiàng)目編譯所用到的插件,一定要區(qū)別于 Module 里面的 dependencies 哟忍,注意閱讀 NOTE 的英文說(shuō)明狡门。上例中我們配置了一個(gè) Gradle 插件和 Kotlin 插件陷寝。
3、項(xiàng)目版本信息
/**
* 應(yīng)用版本相關(guān)配置信息
*/
ext {
applicationId = "com.wf.mvp.mode"
apkName = "MvpMode"
versionCode = 1
versionName = "v1.0"
compileSdkVersion = 29
buildToolsVersion = "29.0.2"
minSdkVersion = 19
targetSdkVersion = 29
}
這里配置的是我們項(xiàng)目的包名其馏、版本號(hào)凤跑、sdk 版本、編譯版本等信息叛复,當(dāng)然了這里我們只是定義仔引,具體的使用是在每個(gè) Module 里面通過(guò) rootProject.applicationId 的形式來(lái)調(diào)用,項(xiàng)目的每個(gè) Module 都通過(guò)這種形式來(lái)配置版本信息后致扯,后續(xù)版本調(diào)整我們就只需要修改這里就 ok 了肤寝。
4、公共 lib 配置
/**
* Module通用lib
*/
ext {
lib_kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
lib_appcompat = 'androidx.appcompat:appcompat:1.1.0'
lib_core_ktx = 'androidx.core:core-ktx:1.2.0'
lib_constraintlayout = 'androidx.constraintlayout:constraintlayout:1.1.3'
lib_junit = 'junit:junit:4.13'
lib_ext_junit = 'androidx.test.ext:junit:1.1.1'
lib_espresso_core = 'androidx.test.espresso:espresso-core:3.2.0'
}
同上面的版本信息一樣抖僵,公用的 lib 庫(kù)我們也可以定義在這里鲤看,子 Module 亦是通過(guò) rootProject.lib_appcompat 的形式來(lái)調(diào)用,當(dāng)然了和上面的版本信息寫(xiě)在一個(gè) ext 方法塊里面也可以耍群,為了區(qū)分我們這里是分開(kāi)寫(xiě)的义桂。
四、Module 的 Gradle 通用配置
??這里 Module 的 Gradle 主要是用來(lái)配置各個(gè) Module 的差異化信息蹈垢,公共的信息均調(diào)用 Project 的 Gradle 里面定義好的慷吊。
??Module 的 Gradle 的配置文件是相應(yīng)的 Module 目錄下面的 build.gradle,這里面主要配置插件引用曹抬、版本信息溉瓶、簽名信息、編譯信息谤民、渠道信息堰酿、APK格式化輸出、第三方框架及 lib 引用 等张足。
1触创、插件引用
// path -> app/build.gradle
apply plugin: 'com.android.application'
// apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
??第一行配置此 Module 為 Application 還是 Library,為 Application 時(shí)可以單獨(dú)運(yùn)行为牍。這里在組件化開(kāi)發(fā)中尤為重要哼绑,可以通過(guò)參數(shù)來(lái)配置此 Module 為 Application 還是 Library。
??后面兩行為配置的 Kotlin 支持插件碉咆,當(dāng)然了這里還可以配置一些其他需要用到的插件抖韩。
2、版本信息
// path -> app/build.gradle
// --------------- wf-update: 2020/5/9 17:53 版本配置信息 ---------------
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion rootProject.buildToolsVersion
defaultConfig {
applicationId rootProject.applicationId
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode rootProject.versionCode
versionName rootProject.versionName
buildConfigField("String", "DEFAULT_CONFIG", "\"default\"")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
??這里配置的是應(yīng)用版本相關(guān)的信息吟逝,此信息均定義在 Project 的 Gradle 里面帽蝶,故這里均引用的 Project 的 Gradle 里面定義的信息。所有的 Module 版本信息都應(yīng)參照這里配置來(lái)保證整個(gè)工程的版本一致。
buildConfigField 定義的字段可以在代碼中通過(guò) BuildConfig.DEFAULT_CONFIG 的形式來(lái)調(diào)用励稳,這在后面講到的版本和渠道里面會(huì)非常有用佃乘。注意這里定義的字符串需要加上雙引號(hào)。
3驹尼、簽名信息
// path -> app/build.gradle
// --------------- wf-update: 2020/5/9 17:55 簽名配置信息 ---------------
signingConfigs {
debug {
}
release {
keyAlias 'mvp'
keyPassword 'mvp123'
storeFile file('../sign/mvp.jks')
storePassword 'mvp123'
}
}
??簽名信息配置沒(méi)什么特別的趣避,簽名文件可以使用 AS 或者其他簽名文件生成工具均可。具體的步驟這里不再贅述新翎,可以自行百度程帕。
4、編譯信息
// path -> app/build.gradle
// --------------- wf-update: 2020/5/20 19:04 版本編譯信息 ---------------
buildTypes {
debug {
buildConfigField("String", "BUILD_TYPES", "\"build_debug\"")
}
release {
buildConfigField("String", "BUILD_TYPES", "\"build_release\"")
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
??編譯信息配置用來(lái)配置我們編譯的版本是 debug 還是 release地啰,不同的版本我們可以配置不同的信息以及變量等愁拭。這里我們?cè)?release 版本中配置了上面定義的簽名信息,而 dubug 沒(méi)有亏吝。當(dāng)我們使用 assemble 命令編譯時(shí)會(huì)在 app/build/outputs/apk 目錄下同時(shí)輸出 debug 和 release 版本的apk岭埠,而單獨(dú)使用 assembleDebug 或者 assembleRelease 只會(huì)輸出對(duì)應(yīng)的一個(gè)版本的apk。
5蔚鸥、渠道信息
// path -> app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wf.mvp.mode"
android:sharedUserId="${SHARED_USER_ID}">
<application ......>
......
<meta-data
android:name="CHANNEL_INFO"
android:value="${CHANNEL_VALUE}" />
</application>
</manifest>
// path -> app/build.gradle
// --------------- wf-update: 2020/5/19 20:36 渠道配置信息 ---------------
flavorDimensions "company", "channel"
productFlavors {
huawei {
dimension "company"
buildConfigField("String", "FLAVOR_COMPANY", "\"huawei\"")
manifestPlaceholders = [
SHARED_USER_ID: "android.uid.huawei",
CHANNEL_VALUE : "huawei"
]
}
xiaomi {
dimension "company"
buildConfigField("String", "FLAVOR_COMPANY", "\"xiaomi\"")
manifestPlaceholders = [
SHARED_USER_ID: "android.uid.xiaomi",
CHANNEL_VALUE : "xiaomi"
]
}
phone {
dimension "channel"
buildConfigField("String", "FLAVOR_COMPANY", "\"phone\"")
buildConfigField("String", "FLAVOR_CHANNEL", "\"phone\"")
manifestPlaceholders = [
SHARED_USER_ID: "android.uid.phone",
CHANNEL_VALUE : "phone"
]
}
tv {
dimension "channel"
buildConfigField("String", "FLAVOR_COMPANY", "\"tv\"")
buildConfigField("String", "FLAVOR_CHANNEL", "\"tv\"")
manifestPlaceholders = [
SHARED_USER_ID: "android.uid.tv",
CHANNEL_VALUE : "tv"
]
}
}
??渠道配置是針對(duì)不同的渠道而進(jìn)行的差異化配置惜论。這里有以下幾點(diǎn)需要說(shuō)明:
- 多渠道維度(flavorDimensions): AS 3.0之后出現(xiàn)的,至少需要定義一個(gè)維度止喷。舉個(gè)栗子:A 廠(chǎng)商生產(chǎn)了 C馆类、D 兩個(gè)產(chǎn)品,B 廠(chǎng)商也生產(chǎn)了 C弹谁、D 兩個(gè)產(chǎn)品乾巧,這里就需要用到二維渠道了,就會(huì)有 AC预愤、AD卧抗、BC、BD 四個(gè)產(chǎn)品鳖粟。
- 渠道維度順序:渠道維度的定義是有先后順序的,如果渠道里面有相同的配置信息拙绊,先定義的維度會(huì)覆蓋后定義的維度向图,如上例中的 FLAVOR_COMPANY、SHARED_USER_ID 和 CHANNEL_VALUE 的值始終都會(huì)是 company 維度下的 huawei 或者 xiaomi标沪,不可能為 channel 維度下的 phone 或者 tv榄攀。可以去 app/build/generated/source/buildConfig 下的 BuildConfig.java 文件中驗(yàn)證金句。
6檩赢、APK格式化輸出
// path -> app/build.gradle
// --------------- wf-update: 2020/5/9 17:58 APK格式化輸出配置 ---------------
applicationVariants.all { variant ->
variant.outputs.all {
def fileName
def formattedDate = new Date().format("yyyy-MM-dd-HHmmss")
if (variant.buildType.name == 'release') {
fileName = "${rootProject.apkName}_${variant.mergedFlavor.versionName}_${formattedDate}_release.apk"
} else {
fileName = "${rootProject.apkName}_${variant.mergedFlavor.versionName}_${formattedDate}_debug.apk"
}
outputFileName = fileName
}
}
??這里也沒(méi)有什么好講的,自行根據(jù)項(xiàng)目來(lái)定義 apk 的輸出名稱(chēng)违寞,默認(rèn)的輸出路徑是 app/build/outputs/apk贞瞒,也可以修改此輸出路徑偶房,但是修改輸出路徑后,當(dāng)我們?cè)谑褂?AS run 來(lái)調(diào)試應(yīng)用的時(shí)候可能會(huì)報(bào)找不到 xxx.apk 的錯(cuò)誤军浆,所以建議不要修改棕洋。
7、第三方框架及 lib 引用
// path -> app/build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation rootProject.lib_kotlin
implementation rootProject.lib_appcompat
implementation rootProject.lib_core_ktx
implementation rootProject.lib_constraintlayout
testImplementation rootProject.lib_junit
androidTestImplementation rootProject.lib_ext_junit
androidTestImplementation rootProject.lib_espresso_core
//引用其他 Module
implementation project(path: ':mvp-kotlin')
implementation project(path: ':mvp-java')
//內(nèi)存泄漏
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
}
??這里主要用來(lái)引用需要的外部庫(kù)文件和 Library Module乒融,通用的庫(kù)我們還是通過(guò) rootProject.lib_appcompat 的形式來(lái)引用我們?cè)?Project 里面定義好的掰盘,保證通用庫(kù)版本統(tǒng)一。注意區(qū)別這里的 dependencies 和我們上面講到的 Project 的 build.gradle 里面的 dependencies赞季。
總結(jié)
??到這里愧捕,我們基礎(chǔ)的、也是大多數(shù)項(xiàng)目必須的通用配置就講完了申钩,任何一個(gè)新項(xiàng)目把這套配置拿過(guò)去基本上都能滿(mǎn)足需求次绘。當(dāng)然了 Gradle 用法遠(yuǎn)不止這些,像是源文件路徑配置典蜕、ndk 配置断盛、編譯檢測(cè)等等,感興趣的童鞋可以自己去研究愉舔。以上就是本篇文章的全部?jī)?nèi)容钢猛,如有錯(cuò)誤的地方或者更好的建議歡迎在下方留言討論,謝謝轩缤!
完整配置的Guthub地址:https://github.com/WangFion/mvp-mode