合肥公司網(wǎng)站建設(shè)搜索引擎優(yōu)化排名seo
文章目錄
- Gradle基礎(chǔ)
- 總結(jié):
- gradle-wrapper
- 項(xiàng)目根目錄下的 build.gradle
- setting.gradle
- 模塊中的 build.gradle
- local.properties 和 gradle.properties
- 組件化:
- 項(xiàng)目下新建一個(gè)Gradle文件
- 定義一個(gè)ext擴(kuò)展區(qū)域
- config.gradle全局基礎(chǔ)配置(使用在項(xiàng)目build中,確保屬性的引用)
- config_build.gradle通用配置(使用在各個(gè)build里(其實(shí)可用也可不用))
- 在build.gradle中導(dǎo)入config.gradle
- Base基礎(chǔ)層:
- 建立一個(gè)libBase模塊
- 修改libbase的builde.gradle
- 組件層(業(yè)務(wù))
- 建立一個(gè)login組件模塊
- 修改login的builde.gradle
- 1.引入config_build文件
- 2.不引入
- 解釋:
- app層:
- 修改App的build.gradle
Gradle基礎(chǔ)
Gradle 是一種基于 Groovy 的構(gòu)建工具,被用于 Android 項(xiàng)目的構(gòu)建、編譯和打包。它提供了強(qiáng)大的構(gòu)建自動(dòng)化功能,使得在 Android 應(yīng)用開(kāi)發(fā)中管理依賴、設(shè)置環(huán)境和自定義構(gòu)建流程變得更加方便和靈活。
在 Android 開(kāi)發(fā)中,Gradle 被廣泛用于構(gòu)建項(xiàng)目、處理依賴、運(yùn)行測(cè)試、生成 APK 等任務(wù)。下面是一些關(guān)于 Android 中的 Gradle 的重要說(shuō)明:
- 構(gòu)建腳本: Android 項(xiàng)目中的 build.gradle 文件是 Gradle 的核心配置文件。它定義了項(xiàng)目的構(gòu)建設(shè)置、依賴關(guān)系和任務(wù)。通常,一個(gè) Android 項(xiàng)目包含根目錄下的 build.gradle 文件和每個(gè)模塊(如 app 模塊)下的 build.gradle 文件。
- 插件: Android Gradle 插件是為了與 Android 構(gòu)建系統(tǒng)集成而設(shè)計(jì)的 Gradle 插件。在項(xiàng)目的 build.gradle 文件中,通過(guò)引入 com.android.application 或 com.android.library 插件,可以使 Gradle 成為適用于 Android 應(yīng)用或庫(kù)的構(gòu)建工具。
- 任務(wù): Gradle 使用任務(wù)(Task)來(lái)定義構(gòu)建過(guò)程中需要執(zhí)行的操作。常見(jiàn)的任務(wù)包括編譯代碼、打包應(yīng)用、運(yùn)行測(cè)試、生成 APK 等。Gradle 支持自定義任務(wù),可以根據(jù)需要擴(kuò)展構(gòu)建過(guò)程。
- 依賴管理: Gradle 管理 Android 項(xiàng)目的依賴關(guān)系。通過(guò) dependencies 塊,可以指定項(xiàng)目所需的外部庫(kù)和模塊。Gradle 可以自動(dòng)從遠(yuǎn)程 Maven 倉(cāng)庫(kù)或本地文件系統(tǒng)下載依賴項(xiàng),并將其包含到項(xiàng)目的構(gòu)建路徑中。
- 變體: Android Gradle 插件引入了變體(Variant)的概念,用于管理不同構(gòu)建類型(如 Debug 和 Release)和不同產(chǎn)品風(fēng)味(如不同的應(yīng)用標(biāo)識(shí)符或資源配置)的構(gòu)建變體。通過(guò)變體,可以針對(duì)不同的構(gòu)建配置生成不同的 APK。
- 構(gòu)建類型和產(chǎn)品風(fēng)味: Android Gradle 插件允許定義多個(gè)構(gòu)建類型和產(chǎn)品風(fēng)味,以滿足不同的需求。構(gòu)建類型可以是 Debug、Release 或自定義的構(gòu)建類型,而產(chǎn)品風(fēng)味可以設(shè)置不同的應(yīng)用標(biāo)識(shí)符、資源和其他配置。
Gradle在Android項(xiàng)目中有兩個(gè)比較重要的文件,那就是工程下的build.gradle和模塊下的build.gradle,如下圖所示:
當(dāng)我們將項(xiàng)目結(jié)構(gòu)切換為Android模式時(shí),打開(kāi)Gradle Scripts,就可以看到排在最前面的是工程的build.gradle,然后是模塊的build.gradle,只要看文件括號(hào)后面的內(nèi)容就知道這個(gè)build.gradle作用的范圍是什么,雖然兩者都是build.gradle,但因?yàn)樽饔梅秶煌?#xff0c;實(shí)際的功能就不同。
① 工程build.gradle
在 Android 工程中,項(xiàng)目的根目錄下有一個(gè)名為 build.gradle 的文件,通常稱為 “工程級(jí) build.gradle”,用于配置整個(gè)項(xiàng)目的構(gòu)建設(shè)置。下面是一個(gè)簡(jiǎn)單的 Android 工程級(jí) build.gradle 文件的示例:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {id 'com.android.application' version '8.1.3' apply falseid 'org.jetbrains.kotlin.android' version '1.9.0' apply false
}
上述示例中的 plugins 塊配置了插件,并指定插件的版本,這是新版本的工程build.gradle,它將一些功能放到settings.gradle中,下面我們會(huì)說(shuō)到。
② 項(xiàng)目build.gradle
在 Android 項(xiàng)目中,每個(gè)模塊(如 app 模塊、library 模塊等)都有一個(gè)對(duì)應(yīng)的模塊級(jí) build.gradle 文件,用于配置該模塊的構(gòu)建設(shè)置和依賴項(xiàng)。下面是一個(gè)簡(jiǎn)單的 Android 模塊級(jí) build.gradle 文件的示例:
plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'
}android {namespace 'com.example.hellokotlin' compileSdk 33 // 指定編譯使用的 Android SDK 版本defaultConfig {applicationId "com.example.hellokotlin" // 應(yīng)用的唯一標(biāo)識(shí)符minSdk 24 // 最低支持的 Android 版本targetSdk 33 // 目標(biāo) Android 版本versionCode 1 // 版本號(hào)versionName "1.0" // 版本名稱testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release { minifyEnabled false // 是否開(kāi)啟代碼混淆proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 混淆規(guī)則文件}}compileOptions { //編譯選項(xiàng)sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions { //Kotlin編譯基于Jvm的版本jvmTarget = '1.8'}// 其他配置項(xiàng),如構(gòu)建變體、簽名配置等
}dependencies { // 依賴項(xiàng)implementation 'androidx.core:core-ktx:1.9.0'implementation 'androidx.appcompat:appcompat:1.6.1'implementation 'com.google.android.material:material:1.8.0'implementation 'androidx.constraintlayout:constraintlayout:2.1.4'testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit:1.1.5'androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
plugins 聲明了所應(yīng)用的插件,例如 ‘com.android.application’ 表示應(yīng)用 Android 應(yīng)用插件,org.jetbrains.kotlin.android表示Kotlin語(yǔ)言插件,如果你使用Java語(yǔ)言開(kāi)發(fā),則不需要這個(gè)插件。
android 塊用于配置 Android 構(gòu)建設(shè)置,其中包括編譯和構(gòu)建的相關(guān)配置。例如,compileSdkVersion 指定了編譯使用的 Android SDK 版本,defaultConfig 定義了默認(rèn)的配置項(xiàng),如應(yīng)用標(biāo)識(shí)符、最低支持版本、目標(biāo)版本等。
buildTypes 塊用于定義不同構(gòu)建類型(如 release、debug)的配置。通過(guò)這個(gè)塊,可以控制是否開(kāi)啟代碼混淆、添加混淆規(guī)則等。
dependencies 聲明了該模塊的依賴項(xiàng)。使用 implementation 關(guān)鍵字可以引入所需的庫(kù)和模塊。例如,androidx.appcompat:appcompat:1.6.1’ 引入了 AndroidX AppCompat 庫(kù)。
如圖中這些則保存在:
可以在文件的其他部分定義自定義任務(wù)和其他配置塊。這些可以根據(jù)項(xiàng)目需求進(jìn)行個(gè)性化配置,例如添加構(gòu)建任務(wù)、自定義變體等。
需要注意的是,每個(gè)模塊都有自己的 build.gradle 文件,但具體的配置選項(xiàng)和依賴項(xiàng)可能因模塊類型和項(xiàng)目需求而有所不同。建議參考具體模塊的 build.gradle 文件和官方文檔來(lái)了解和調(diào)整配置。
③ settings.gradle
settings.gradle 是 Android 項(xiàng)目的根目錄下的一個(gè)重要文件,它用于配置項(xiàng)目的模塊和構(gòu)建設(shè)置。
這里需要說(shuō)明一下,實(shí)際上關(guān)于settings.gradle項(xiàng)目在舊版本的Android Studio上沒(méi)有這么多內(nèi)容,只是對(duì)工程下面的模塊進(jìn)行管理,我們看看之前的settings.gradle中有什么內(nèi)容,如下所示:
rootProject.name = "FakeQQMusic"
include ':app'
之前的內(nèi)容比較簡(jiǎn)單,當(dāng)你需要改動(dòng)項(xiàng)目名稱或者增加項(xiàng)目中的模塊時(shí)這個(gè)文件才會(huì)發(fā)生變化。大概是在大黃蜂版本開(kāi)始發(fā)生了變化,將原本屬于工程級(jí)build.gradle中的一些功能挪到了settings.gradle中,新版本代碼如下所示:
下面是一個(gè)常見(jiàn)的 Android settings.gradle 文件的示例及其說(shuō)明:
// pluginManagement用于管理Gradle插件的倉(cāng)庫(kù)相關(guān)配置
pluginManagement {repositories {// google倉(cāng)庫(kù)配置,用于獲取特定的插件google {content {// 通過(guò)正則表達(dá)式匹配包含以com.android開(kāi)頭的插件組includeGroupByRegex("com\\.android.*")// 通過(guò)正則表達(dá)式匹配包含以com.google開(kāi)頭的插件組includeGroupByRegex("com\\.google.*")// 通過(guò)正則表達(dá)式匹配包含以androidx開(kāi)頭的插件組includeGroupByRegex("androidx.*")}}// 添加Maven中央倉(cāng)庫(kù),可獲取眾多開(kāi)源插件和依賴mavenCentral()// Gradle官方的插件倉(cāng)庫(kù),用于獲取Gradle插件gradlePluginPortal()}
}// dependencyResolutionManagement用于控制項(xiàng)目如何解析依賴
dependencyResolutionManagement {// 設(shè)置依賴倉(cāng)庫(kù)的模式,FAIL_ON_PROJECT_REPOS表示如果項(xiàng)目級(jí)別的倉(cāng)庫(kù)配置不符合預(yù)期,構(gòu)建將失敗repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {// 使用google倉(cāng)庫(kù)獲取與Google和Android相關(guān)的依賴google()// 使用Maven中央倉(cāng)庫(kù)獲取各種開(kāi)源庫(kù)依賴mavenCentral()}
}// 設(shè)置根項(xiàng)目的名稱為FakeQQMusic,方便在構(gòu)建系統(tǒng)等環(huán)境中標(biāo)識(shí)項(xiàng)目
rootProject.name = "FakeQQMusic"// 在多模塊項(xiàng)目中,包含名為'app'的子模塊,通常是Android項(xiàng)目的主要應(yīng)用模塊,會(huì)參與構(gòu)建過(guò)程
include ':app'
我們著重說(shuō)明一下增加的部分, settings.gradle 文件中的 pluginManagement 和 dependencyResolutionManagement 配置塊中的內(nèi)容。
這些配置塊用于配置 Gradle 插件的倉(cāng)庫(kù)和依賴項(xiàng)的解析方式。
-
在 pluginManagement 配置塊中:
- repositories 聲明了用于解析 Gradle 插件的倉(cāng)庫(kù)。示例中的配置包括 google()、mavenCentral() 和 gradlePluginPortal()。通過(guò)這些倉(cāng)庫(kù),Gradle 將查找并下載所需的插件。
-
在 dependencyResolutionManagement 配置塊中:
- repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 設(shè)置了倉(cāng)庫(kù)模式為 RepositoriesMode.FAIL_ON_PROJECT_REPOS。這表示如果項(xiàng)目中存在本地的倉(cāng)庫(kù),則構(gòu)建過(guò)程將失敗。該配置用于強(qiáng)制 Gradle 僅使用遠(yuǎn)程倉(cāng)庫(kù)解析依賴項(xiàng),而不依賴本地倉(cāng)庫(kù)。
- repositories 聲明了用于解析項(xiàng)目依賴項(xiàng)的倉(cāng)庫(kù)。示例中的配置包括 google() 和 mavenCentral()。
通過(guò)這些倉(cāng)庫(kù),Gradle 將查找并下載項(xiàng)目所需的依賴項(xiàng)。
這些配置塊的作用是為 Gradle 構(gòu)建過(guò)程提供正確的插件和依賴項(xiàng)解析環(huán)境。配置中的倉(cāng)庫(kù)聲明可以根據(jù)項(xiàng)目的需求進(jìn)行調(diào)整,以確保構(gòu)建正常進(jìn)行。
④ gradle.properties
gradle.properties 文件是一個(gè)位于根目錄下的重要配置文件,用于設(shè)置 Gradle 構(gòu)建系統(tǒng)的全局屬性。它可以包含一些常用的配置屬性和自定義屬性,以影響項(xiàng)目的構(gòu)建過(guò)程。其中讓人印象最深刻的莫過(guò)于Google將庫(kù)統(tǒng)一遷移到AndroidX下,當(dāng)時(shí)就需要改一個(gè)屬性android.useAndroidX=true,現(xiàn)在這已經(jīng)是一個(gè)常駐屬性了,之前的V4、V7的庫(kù)你只會(huì)在一些老項(xiàng)目上看到,屬于時(shí)代的眼淚了,下面我們看看這個(gè)gradle.properties中的內(nèi)容
# 指定用于守護(hù)進(jìn)程的 JVM 參數(shù)。
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# 使用AndroidX
android.useAndroidX=true
# Kotlin 代碼樣式:“official 官方”或“obsolete 過(guò)時(shí)”:
kotlin.code.style=official
//kotlin的
# 啟用每個(gè)庫(kù)的 R 類的命名空間,以便其 R 類僅包含庫(kù)本身中聲明的資源,而不包含庫(kù)依賴項(xiàng)中的資源,從而減小該庫(kù)的 R 類的大小
android.nonTransitiveRClass=true
項(xiàng)目范圍的 Gradle 設(shè)置。
IDE(例如 Android Studio)用戶:
通過(guò) IDE 配置的 Gradle 設(shè)置 將會(huì)覆蓋
本文件中指定的任何設(shè)置。
如需了解有關(guān)如何配置構(gòu)建環(huán)境的更多詳細(xì)信息,請(qǐng)?jiān)L問(wèn)
http://www.gradle.org/docs/current/userguide/build_environment.html
指定用于守護(hù)進(jìn)程的 JVM 參數(shù)。
該設(shè)置對(duì)于調(diào)整內(nèi)存設(shè)置特別有用。
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
這一行表示設(shè)置最大堆內(nèi)存為 2048MB,并將文件編碼指定為 UTF-8,這樣可以在 Gradle 守護(hù)進(jìn)程運(yùn)行時(shí)按照這個(gè)內(nèi)存分配和編碼規(guī)則來(lái)處理相關(guān)任務(wù),有助于避免因內(nèi)存不足等問(wèn)題導(dǎo)致的構(gòu)建錯(cuò)誤,同時(shí)保證文件讀寫等操作時(shí)編碼的一致性。
當(dāng)進(jìn)行配置后,Gradle 將以試驗(yàn)性的并行模式運(yùn)行。
此選項(xiàng)僅應(yīng)在解耦項(xiàng)目中使用。如需了解更多詳細(xì)信息,請(qǐng)?jiān)L問(wèn)
https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
org.gradle.parallel=true
這里如果啟用了該設(shè)置(當(dāng)前被注釋掉了),意味著多個(gè)模塊或者任務(wù)可以并行構(gòu)建,能夠加快整體構(gòu)建速度,但要確保項(xiàng)目是符合解耦條件的,不然可能會(huì)出現(xiàn)一些預(yù)料之外的構(gòu)建問(wèn)題。
AndroidX 包結(jié)構(gòu),用于更清晰地表明哪些包是隨 Android 操作系統(tǒng)捆綁在一起的,以及哪些包是與你的應(yīng)用程序的 APK 一起打包的。
https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
這一設(shè)置啟用了 AndroidX,AndroidX 是對(duì)之前 Android 支持庫(kù)的重構(gòu)和改進(jìn),采用了新的包名體系,有助于更好地區(qū)分系統(tǒng)相關(guān)和應(yīng)用自身相關(guān)的庫(kù)包,方便進(jìn)行依賴管理以及適配不同版本的 Android 系統(tǒng)等操作。
啟用每個(gè)庫(kù)的 R 類的命名空間,使得其 R 類僅包含在該庫(kù)自身中聲明的資源,而不包含來(lái)自該庫(kù)依賴項(xiàng)的資源,
從而減小該庫(kù)的 R 類的大小。
android.nonTransitiveRClass=true
這一設(shè)置讓每個(gè)庫(kù)的資源管理更加獨(dú)立,避免因?yàn)橐蕾噦鬟f導(dǎo)致 R 類中包含過(guò)多不必要的資源引用,進(jìn)而減小了 R 類占用的空間,對(duì)于優(yōu)化 APK 大小等方面有一定幫助,使得資源管理更加清晰和高效。
⑤ gradle-wrapper.properties
在 Android 項(xiàng)目中,gradle-wrapper.properties 文件位于根目錄下的 gradle/wrapper 文件夾中,它用于配置 Gradle Wrapper。Gradle Wrapper 是一個(gè)與項(xiàng)目一起分發(fā)的 Gradle 版本管理工具,它可以確保每個(gè)構(gòu)建都使用指定版本的 Gradle,而無(wú)需手動(dòng)安裝或配置 Gradle。
gradle-wrapper.properties 文件包含了一些重要的配置屬性,用于指定 Gradle Wrapper 的行為和使用的 Gradle 版本。下面看一個(gè)示例:
#Tue Oct 22 17:28:24 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
上述示例中的 gradle-wrapper.properties 文件包含了以下重要配置和說(shuō)明:
- distributionBase 和 distributionPath 配置了 Gradle Wrapper 下載和緩存 Gradle 發(fā)行版本的基本路徑。默認(rèn)情況下,它們指向 GRADLE_USER_HOME,即用戶的 Gradle 目錄。
- zipStoreBase 和 zipStorePath 配置了壓縮文件的基本路徑,Gradle Wrapper 會(huì)將下載的 Gradle 發(fā)布文件存儲(chǔ)在這里。默認(rèn)情況下,它們也指向 GRADLE_USER_HOME。
- distributionUrl 指定了要使用的 Gradle 發(fā)布版本的 URL。通過(guò)指定這個(gè) URL,Gradle Wrapper 會(huì)自動(dòng)下載并使用該版本構(gòu)建項(xiàng)目。
gradle-wrapper.properties 文件的作用是為項(xiàng)目提供一個(gè)指定版本的 Gradle。當(dāng)你使用 Gradle Wrapper 執(zhí)行構(gòu)建時(shí),它會(huì)根據(jù)該文件中的配置自動(dòng)下載所需版本的 Gradle。這有助于項(xiàng)目的一致性和可移植性,因?yàn)槊總€(gè)開(kāi)發(fā)者都可以使用相同的 Gradle 版本構(gòu)建項(xiàng)目,無(wú)需手動(dòng)配置。
需要注意的是,如果需要更改 Gradle 版本或其他配置屬性,可以在 gradle-wrapper.properties 文件中進(jìn)行相應(yīng)的修改。比如我可能Gradle需要升級(jí)8.1,那么你在改動(dòng)之后點(diǎn)擊Sync Now進(jìn)行下載配置,具體的配置方式和詳細(xì)說(shuō)明可以參考官方文檔。
⑥ local.properties
local.properties 文件是一個(gè)位于根目錄下的本地配置文件,它用于指定本地開(kāi)發(fā)環(huán)境中的一些路徑和屬性。該文件通常用于定義 SDK 和其他構(gòu)建工具的位置,以便 Gradle 可以正確定位并使用它們。
以下是一個(gè)示例 local.properties 文件的內(nèi)容及其說(shuō)明:
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\jetbrains\\Sdk//可能會(huì)有
//sdk.dir=D\:\\Android\\Sdk
//ndk.dir=D\:\\Android\\Sdk\\ndk\\26.1.10909125
上述示例中的 local.properties 文件包含了以下重要配置和說(shuō)明:
- sdk.dir 配置了 Android SDK 的位置。這個(gè)配置屬性指定了 Android SDK 的根目錄路徑,Gradle 將使用該路徑來(lái)查找構(gòu)建所需的 Android 庫(kù)和工具。
- ndk.dir 配置了 Android NDK 的位置。這個(gè)配置屬性指定了 Android NDK 的根目錄路徑,Gradle 將使用該路徑來(lái)支持使用 C/C++ 編寫的本地代碼。
通過(guò)在 local.properties 文件中設(shè)置這些屬性,Android 開(kāi)發(fā)工具鏈(如 Android Studio 和 Gradle)可以找到和使用正確的 SDK、NDK 版本,并確保項(xiàng)目的構(gòu)建過(guò)程能夠正常進(jìn)行。
請(qǐng)注意,local.properties 文件通常是在 Android 項(xiàng)目的每個(gè)開(kāi)發(fā)者的本地環(huán)境中設(shè)置。這意味著每個(gè)開(kāi)發(fā)者可以根據(jù)自己的系統(tǒng)配置和需求來(lái)設(shè)置這些屬性,而不會(huì)影響到其他開(kāi)發(fā)者。默認(rèn)情況下你是不需要配置ndk的路徑的,需要根據(jù)你的實(shí)際開(kāi)發(fā)環(huán)境和需求來(lái)設(shè)置 local.properties 文件中的屬性。確保路徑和屬性值與你的系統(tǒng)配置和目錄結(jié)構(gòu)一致。
總結(jié):
gradle-wrapper
gradle-wrapper
簡(jiǎn)單來(lái)說(shuō)就是對(duì) Gradle 的一層封裝。為什么需要再封裝一層呢?主要有三點(diǎn)原因:
- 確保 版本一致性: 讓團(tuán)隊(duì)成員都使用項(xiàng)目指定的相同版本進(jìn)行構(gòu)建,避免因版本差異導(dǎo)致的構(gòu)建問(wèn)題
- 方便 項(xiàng)目遷移和共享:當(dāng)項(xiàng)目需要遷移到其他環(huán)境或與他人共享時(shí),不需要擔(dān)心 Gradle 版本的問(wèn)題,因?yàn)?Wrapper 會(huì)處理好版本的適配。
- 版本更新管理:項(xiàng)目可以方便地更新 Gradle 版本,只需在 Wrapper 的配置中修改版本號(hào),所有使用 Wrapper 的開(kāi)發(fā)者在下次構(gòu)建時(shí)都會(huì)自動(dòng)獲取并使用新的版本。
從上圖可以看到,gradle-wrapper 相關(guān)的文件有四種,分別是:
gradle-wrapper.jar
:主要是Gradle的運(yùn)行邏輯,包含下載Gradle;gradle-wrapper.properties
:gradle-wrapper 的配置文件,核心是定義了Gradle版本;gradlew
:gradle wrapper的簡(jiǎn)稱,linux下的執(zhí)行腳本gradlew.bat
:windows下的執(zhí)行腳本
由于這篇文章主要是講配置文件的,這里就主要看看 gradle-wrapper.properties 的文件:
#Tue Oct 22 17:28:24 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
參數(shù)介紹如下
distributionBase
:下載的Gradle的壓縮包解壓后的主目錄;zipStoreBase
:同distributionBase,不過(guò)是存放zip壓縮包的主目錄;distributionPath
:相對(duì)于distributionBase的解壓后的Gradle的路徑,為wrapper/dists;zipStorePath
:同distributionPath,不過(guò)是存放zip壓縮包的;distributionUrl
:Gradle版本的下載地址,所有的版本可以看Gradle Distributions。這里有幾種類型,分別為:doc
:用戶文檔;bin
:二進(jìn)制文件;all
:包含源碼、用戶文檔、二進(jìn)制文件等;
項(xiàng)目根目錄下的 build.gradle
項(xiàng)目根目錄下的 build.gradle
的文件內(nèi)容如下所示:
plugins {
alias(libs.plugins.android.application) apply false
}
plugins
聲明的是用來(lái)構(gòu)建應(yīng)用的插件列表。其中 apply false
表示不將該 plugin 應(yīng)用于當(dāng)前項(xiàng)目,一般是在需要使用的模塊的 build.gradle
文件中聲明使用。
在7.0
以前,Gradle 可以設(shè)置很多通用的配置;現(xiàn)在在 7.0
版本之后,這些配置移動(dòng)到了 setting.gradle
文件。
setting.gradle
setting.gradle
文件內(nèi)容如下所示:
// pluginManagement用于管理Gradle插件的倉(cāng)庫(kù)相關(guān)配置
pluginManagement {repositories {// google倉(cāng)庫(kù)配置,用于獲取特定的插件google {content {// 通過(guò)正則表達(dá)式匹配包含以com.android開(kāi)頭的插件組includeGroupByRegex("com\\.android.*")// 通過(guò)正則表達(dá)式匹配包含以com.google開(kāi)頭的插件組includeGroupByRegex("com\\.google.*")// 通過(guò)正則表達(dá)式匹配包含以androidx開(kāi)頭的插件組includeGroupByRegex("androidx.*")}}// 添加Maven中央倉(cāng)庫(kù),可獲取眾多開(kāi)源插件和依賴mavenCentral()// Gradle官方的插件倉(cāng)庫(kù),用于獲取Gradle插件gradlePluginPortal()}
}// dependencyResolutionManagement用于控制項(xiàng)目如何解析依賴
dependencyResolutionManagement {// 設(shè)置依賴倉(cāng)庫(kù)的模式,FAIL_ON_PROJECT_REPOS表示如果項(xiàng)目級(jí)別的倉(cāng)庫(kù)配置不符合預(yù)期,構(gòu)建將失敗repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {// 使用google倉(cāng)庫(kù)獲取與Google和Android相關(guān)的依賴google()// 使用Maven中央倉(cāng)庫(kù)獲取各種開(kāi)源庫(kù)依賴mavenCentral()}
}// 設(shè)置根項(xiàng)目的名稱為FakeQQMusic,方便在構(gòu)建系統(tǒng)等環(huán)境中標(biāo)識(shí)項(xiàng)目
rootProject.name = "FakeQQMusic"// 在多模塊項(xiàng)目中,包含名為'app'的子模塊,通常是Android項(xiàng)目的主要應(yīng)用模塊,會(huì)參與構(gòu)建過(guò)程
include ':app'
顧名思義,setting.gradle
文件主要存儲(chǔ)項(xiàng)目相關(guān)的設(shè)置信息。比如說(shuō)可以在 setting.gradle
文件中設(shè)置了插件倉(cāng)庫(kù)位置、依賴倉(cāng)庫(kù)位置這些通用的配置;以及指定項(xiàng)目構(gòu)建需要依賴哪些模塊。
模塊中的 build.gradle
plugins {// 當(dāng)前模塊應(yīng)用的插件// 使用libs版本目錄中定義的android.application插件(通過(guò)前面的版本目錄配置關(guān)聯(lián)),// 通常這個(gè)插件用于將當(dāng)前模塊配置為一個(gè)可運(yùn)行的Android應(yīng)用程序模塊alias(libs.plugins.android.application)
}android {// android 相關(guān)的配置信息,會(huì)被引入的 com.android.application 插件使用// 定義應(yīng)用的命名空間,用于在Android系統(tǒng)中唯一標(biāo)識(shí)該應(yīng)用,類似于包名的作用namespace 'com.example.fakeqqmusic'// 指定編譯項(xiàng)目所使用的SDK版本,這里設(shè)置為34,表示使用Android SDK 34進(jìn)行編譯compileSdk 34defaultConfig {// 應(yīng)用在Android系統(tǒng)中的唯一標(biāo)識(shí)符,等同于早期的包名概念,用于安裝、啟動(dòng)等操作applicationId "com.example.fakeqqmusic"// 定義應(yīng)用支持的最低Android系統(tǒng)版本,這里設(shè)置為28,表示該應(yīng)用能在Android 28及以上版本運(yùn)行minSdk 28// 定義應(yīng)用的目標(biāo)Android系統(tǒng)版本,即主要針對(duì)該版本進(jìn)行功能優(yōu)化和測(cè)試,這里是34targetSdk 34// 應(yīng)用的版本代碼,是一個(gè)整數(shù),用于在應(yīng)用市場(chǎng)等場(chǎng)景區(qū)分不同版本,每次發(fā)布新版本時(shí)通常需要遞增versionCode 1// 應(yīng)用的版本名稱,是一個(gè)字符串,通常是方便用戶識(shí)別的版本號(hào)形式,如"1.0",可以按照自己的規(guī)則來(lái)命名versionName "1.0"// 指定用于運(yùn)行Android測(cè)試用例的測(cè)試運(yùn)行器,這里使用的是AndroidJUnitRunner,它是Android測(cè)試框架中常用的運(yùn)行器testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {// 是否啟用代碼壓縮和混淆,設(shè)置為false表示在生成發(fā)布版本(release)時(shí)不進(jìn)行代碼壓縮和混淆操作。// 如果設(shè)置為true,則會(huì)根據(jù)下面指定的proguardFiles進(jìn)行代碼的壓縮和混淆處理minifyEnabled false// 指定Proguard(代碼混淆工具)的配置文件,// 第一個(gè)文件是Android SDK自帶的默認(rèn)優(yōu)化配置文件,第二個(gè)是項(xiàng)目自定義的規(guī)則文件,// 兩者結(jié)合起來(lái)用于確定具體的代碼混淆規(guī)則和方式proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {// 指定項(xiàng)目源代碼兼容的Java版本,這里設(shè)置為Java 8版本,意味著可以在項(xiàng)目中使用Java 8的語(yǔ)法特性進(jìn)行編碼sourceCompatibility JavaVersion.VERSION_1_8// 指定項(xiàng)目編譯生成的字節(jié)碼兼容的Java版本,同樣設(shè)置為Java 8,確保生成的字節(jié)碼能在Java 8及以上的運(yùn)行環(huán)境正常運(yùn)行targetCompatibility JavaVersion.VERSION_1_8}buildFeatures {// 啟用ViewBinding功能,ViewBinding是一種用于更方便地在代碼中訪問(wèn)和操作XML布局文件中視圖的機(jī)制,// 它會(huì)為每個(gè)XML布局文件生成對(duì)應(yīng)的綁定類,減少了 findViewById 等操作的繁瑣性和出錯(cuò)可能viewBinding true// 啟用DataBinding功能,DataBinding允許將數(shù)據(jù)和布局文件進(jìn)行綁定,方便實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)的UI展示,// 可以在布局文件中直接使用數(shù)據(jù)對(duì)象和相關(guān)表達(dá)式,使數(shù)據(jù)與視圖的交互更加簡(jiǎn)潔直觀dataBinding true}
}dependencies {// 引入appcompat庫(kù),這個(gè)庫(kù)提供了對(duì)Android早期版本的兼容性支持,比如一些UI組件和功能,// 它的版本信息從前面配置的libs.versions.toml文件中通過(guò)libs.appcompat獲取implementation libs.appcompat// 引入material庫(kù),用于在應(yīng)用中使用符合Material Design規(guī)范的UI組件和樣式,// 同樣其版本是根據(jù)libs.versions.toml里的配置通過(guò)libs.material獲取implementation libs.material
}
如上代碼所示,模塊中的 build.gradle
文件中主要設(shè)置了構(gòu)建需要的信息,這些信息最后會(huì)被應(yīng)用的插件來(lái)使用。
local.properties 和 gradle.properties
local.properties 和 gradle.properties 文件都是存儲(chǔ)配置信息。不同的是,local.properties 設(shè)置的是本地的特殊配置,比如sdk的位置;而gradle.properties 設(shè)置的是項(xiàng)目相關(guān)的配置。
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\jetbrains\\Sdk
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
在使用上, local.properties 設(shè)置的屬性不能直接使用,只能通過(guò)文件讀取。而 gradle.properties中自定義屬性,可以在gradle中可以直接使用。但是對(duì)于 xxx.xxx 格式的屬性,需要讀取文件獲取它的屬性值,不能直接使用。 local.properties 示例如下:
// 創(chuàng)建Properties對(duì)象Properties properties = new Properties();try {// 通過(guò)文件輸入流加載local.properties文件FileInputStream fileInputStream = new FileInputStream(project.getRootProject().getFile("local.properties"));properties.load(fileInputStream);// 獲取sdk.dir屬性的值String sdkDir = properties.getProperty("sdk.dir");// 打印sdk.dir的值System.out.println("sdkDir = " + sdkDir);// 關(guān)閉文件輸入流fileInputStream.close();} catch (IOException e) {e.printStackTrace();}
gradle.properties 讀取配置示例如下:
//在build.gradle腳本中使用String test = "someValue"; // 假設(shè)這是從某個(gè)地方獲取的屬性值System.out.println("test = " + test);// 讀取 gradle.properties 文件Properties properties = new Properties();try {properties.load(new FileInputStream("gradle.properties"));String androidx = properties.getProperty("android.useAndroidX");System.out.println("androidx = " + androidx);} catch (IOException e) {e.printStackTrace();}
組件化:
抽離共用的build.gradle版本數(shù)據(jù)
我們?cè)贏PP開(kāi)發(fā)過(guò)程中肯定會(huì)涉及到不同的手機(jī)版本信息,系統(tǒng)信息等等。如果每個(gè)模塊的信息都是獨(dú)立的,那么一旦出現(xiàn)版本問(wèn)題需要修改的情況,將會(huì)變得非常麻煩。
這時(shí)就需要使用config.gradle統(tǒng)一管理項(xiàng)目的依賴庫(kù)
項(xiàng)目下新建一個(gè)Gradle文件
用于存儲(chǔ)項(xiàng)目基本信息,在這里面,我們寫上所有依賴庫(kù),以及項(xiàng)目中sdk等等的版本號(hào),然后直接讓build .gradle去apply它,之后有什么版本的修改升級(jí)就可以直接在這里改。
定義一個(gè)ext擴(kuò)展區(qū)域
config.gradle全局基礎(chǔ)配置(使用在項(xiàng)目build中,確保屬性的引用)
用于定義額外的屬性和變量,以便在整個(gè)構(gòu)建腳本中共享和重復(fù)使用。
//在 Gradle 構(gòu)建腳本中定義了一些 Android 項(xiàng)目的配置和依賴項(xiàng)版本信息。
ext {isDebug = false; //當(dāng)為true時(shí)代表調(diào)試模式,組件可以單獨(dú)運(yùn)行。如果是false代表編譯打包/**compileSdkVersion:指定用于編譯應(yīng)用程序的 Android SDK 版本。minSdkVersion:指定應(yīng)用程序可以運(yùn)行的最低 Android 版本。targetSdkVersion:指定應(yīng)用程序目標(biāo)的 Android 版本。versionCode:用于標(biāo)識(shí)應(yīng)用程序版本的整數(shù)值。versionName:用于標(biāo)識(shí)應(yīng)用程序版本的字符串值。*/android = [compileSdkVersion: 33,minSdkVersion : 32,targetSdkVersion : 33,versionCode : 1,versionName : "1.0"]/*** 這是每個(gè)模塊的application地址*/applicationId = ["app" : "com.example.dome","live" : "com.example.module.live","net" : "com.example.module.net","login": "com.example.module.login","router": "com.example.module.librouter"]//定義了一些常見(jiàn)的 Android 庫(kù)的依賴項(xiàng),包括 AppCompat 庫(kù)、Material Design 庫(kù)和 ConstraintLayout 庫(kù)。library = ["appcompat" : "androidx.appcompat:appcompat:1.6.1","material" : "com.google.android.material:material:1.5.0","constraintlayout": "androidx.constraintlayout:constraintlayout:2.1.4"]//第三方庫(kù)單獨(dú)放置libGson = "com.google.code.gson:gson:2.8.6"libARouter = "com.alibaba:arouter-api:1.5.2"libARouterCompiler = "com.alibaba:arouter-compiler:1.5.2"
}
config_build.gradle通用配置(使用在各個(gè)build里(其實(shí)可用也可不用))
/*** 整個(gè)項(xiàng)目(app/module)的通用gradle配置* 需要自行確定namespace。需要自行動(dòng)態(tài)判定module是屬于application(并配置applicationId),還是library。* 默認(rèn)依賴基礎(chǔ)組件module,(:modulesBase:lib_base)* 這段注釋說(shuō)明了該配置文件的整體用途,它旨在為整個(gè)項(xiàng)目(無(wú)論是應(yīng)用模塊還是庫(kù)模塊)提供通用的Gradle配置信息。* 同時(shí)提到了需要手動(dòng)處理一些事項(xiàng),比如確定命名空間以及判斷模塊類型并相應(yīng)配置應(yīng)用標(biāo)識(shí)(針對(duì)應(yīng)用模塊),* 還指出默認(rèn)會(huì)依賴一個(gè)名為'modulesBase:lib_base'的基礎(chǔ)組件模塊。*/// 應(yīng)用'org.jetbrains.kotlin.android'插件,這表明當(dāng)前模塊是使用Kotlin語(yǔ)言進(jìn)行Android開(kāi)發(fā)的,
// 該插件會(huì)為Kotlin在Android項(xiàng)目中的編譯、構(gòu)建等流程提供相應(yīng)的支持和配置
apply plugin: 'org.jetbrains.kotlin.android'android {// rootProject 是指項(xiàng)目的根項(xiàng)目,這里從根項(xiàng)目的擴(kuò)展屬性(ext)中獲取android.compileSdk的值,// 用于指定當(dāng)前模塊編譯所使用的Android SDK版本,通過(guò)這種方式可以在根項(xiàng)目統(tǒng)一管理所有模塊的編譯SDK版本compileSdk rootProject.ext.android.compileSdkdefaultConfig {// 從根項(xiàng)目的擴(kuò)展屬性(ext)中獲取android.minSdk的值,來(lái)定義當(dāng)前模塊支持的最低Android系統(tǒng)版本,// 確保模塊能在該版本及以上的Android設(shè)備上正常運(yùn)行,避免在過(guò)低版本系統(tǒng)上出現(xiàn)兼容性問(wèn)題minSdk rootProject.ext.android.minSdk// 同樣從根項(xiàng)目擴(kuò)展屬性獲取android.targetSdk的值,確定模塊的目標(biāo)Android系統(tǒng)版本,// 即開(kāi)發(fā)過(guò)程中重點(diǎn)針對(duì)該版本進(jìn)行功能優(yōu)化和測(cè)試,保證在該目標(biāo)版本下功能表現(xiàn)最佳且兼容性良好targetSdk rootProject.ext.android.targetSdk// 從根項(xiàng)目擴(kuò)展屬性獲取android.versionCode的值,作為應(yīng)用的版本代碼,它是一個(gè)整數(shù),// 用于在應(yīng)用發(fā)布等場(chǎng)景下(例如應(yīng)用市場(chǎng))區(qū)分不同版本,每次發(fā)布新版本時(shí)通常需要按照一定規(guī)則遞增該數(shù)值versionCode rootProject.ext.android.versionCode// 從根項(xiàng)目擴(kuò)展屬性獲取android.versionName的值,作為應(yīng)用的版本名稱,它是一個(gè)字符串,// 一般采用方便用戶識(shí)別的版本號(hào)形式(如"1.0"),開(kāi)發(fā)團(tuán)隊(duì)可以按照自己的版本命名規(guī)則來(lái)設(shè)定versionName rootProject.ext.android.versionName// 指定用于運(yùn)行Android測(cè)試用例的測(cè)試運(yùn)行器,這里使用的是AndroidJUnitRunner,// 它是Android測(cè)試框架中常用的運(yùn)行器,便于編寫和執(zhí)行單元測(cè)試等各類測(cè)試任務(wù)testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"javaCompileOptions {annotationProcessorOptions {// 為注解處理器傳遞參數(shù),這里將當(dāng)前項(xiàng)目的名稱(通過(guò)project.getName()獲取)作為參數(shù)傳遞給ARouter模塊相關(guān)的注解處理器。// ARouter是一個(gè)用于Android的路由框架,在使用其注解處理器(APT)時(shí),需要傳遞模塊名稱這樣的參數(shù),// 以便在編譯階段正確處理路由相關(guān)的注解信息,生成相應(yīng)的路由映射代碼等arguments = [AROUTER_MODULE_NAME: project.getName()]}}}buildTypes {release {// 是否啟用代碼壓縮和混淆,設(shè)置為false表示在生成發(fā)布版本(release)時(shí)不進(jìn)行代碼壓縮和混淆操作。// 如果設(shè)置為true,則會(huì)根據(jù)下面指定的proguardFiles進(jìn)行代碼的壓縮和混淆處理,// 代碼壓縮和混淆有助于減小APK大小以及保護(hù)代碼邏輯不被輕易反編譯分析minifyEnabled false// 指定Proguard(代碼混淆工具)的配置文件,// 第一個(gè)文件是Android SDK自帶的默認(rèn)優(yōu)化配置文件,第二個(gè)是項(xiàng)目自定義的規(guī)則文件,// 兩者結(jié)合起來(lái)用于確定具體的代碼混淆規(guī)則和方式,確保在進(jìn)行代碼混淆時(shí)按照期望的要求處理代碼proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {// 指定項(xiàng)目源代碼兼容的Java版本,這里設(shè)置為Java 8版本,意味著在項(xiàng)目中可以使用Java 8的語(yǔ)法特性進(jìn)行編碼,// 例如Lambda表達(dá)式、Stream API等,方便開(kāi)發(fā)者利用更現(xiàn)代的語(yǔ)言特性來(lái)編寫代碼sourceCompatibility JavaVersion.VERSION_1_8// 指定項(xiàng)目編譯生成的字節(jié)碼兼容的Java版本,同樣設(shè)置為Java 8,確保生成的字節(jié)碼能在Java 8及以上的運(yùn)行環(huán)境正常運(yùn)行,// 這保證了編譯后的代碼可以在符合要求的Java運(yùn)行時(shí)環(huán)境中正確執(zhí)行targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {// 針對(duì)Kotlin語(yǔ)言,指定其編譯后的字節(jié)碼所兼容的JVM目標(biāo)版本為Java 8,// 這樣在Kotlin代碼中可以使用與Java 8兼容的特性以及語(yǔ)法糖等,確保Kotlin代碼能在相應(yīng)的JVM環(huán)境下正確運(yùn)行jvmTarget = '1.8'}
}dependencies {// 使用implementation不傳遞依賴,可以防止重復(fù)依賴或依賴沖突。// 這種依賴方式意味著引入的庫(kù)只會(huì)在當(dāng)前模塊內(nèi)部使用,不會(huì)將該依賴傳遞給依賴當(dāng)前模塊的其他模塊,// 有助于控制依賴關(guān)系的復(fù)雜性,避免不必要的依賴傳遞導(dǎo)致的問(wèn)題,例如版本沖突等。// 引入項(xiàng)目中名為'modulesBase:lib_base'的模塊,這里推測(cè)是項(xiàng)目的一個(gè)基礎(chǔ)組件模塊,// 可能包含了一些通用的功能、工具類或者資源等,供當(dāng)前模塊使用implementation project(':modulesBase:lib_base')// ARouter 注解處理器 APT需要在每個(gè)使用的組件的build.gradle去添加,并在defaultConfig里添加project.getName。這里屬于通用配置,一次配置完。// 從根項(xiàng)目擴(kuò)展屬性(ext)中獲取arouter_compiler對(duì)應(yīng)的注解處理器依賴,引入該依賴用于處理ARouter框架相關(guān)的注解,// 在編譯階段通過(guò)注解處理器自動(dòng)生成路由相關(guān)的代碼,實(shí)現(xiàn)頁(yè)面之間的路由跳轉(zhuǎn)等功能,// 這里通過(guò)在通用配置中添加,避免在每個(gè)使用ARouter的模塊中都重復(fù)配置該依賴annotationProcessor rootProject.ext.arouter_compiler// 引入JUnit測(cè)試框架,版本為4.13.2,用于在普通測(cè)試(test)環(huán)境下編寫和執(zhí)行單元測(cè)試,// 幫助開(kāi)發(fā)者驗(yàn)證模塊內(nèi)各個(gè)類和方法的功能正確性testImplementation 'junit:junit:4.13.2'// 引入JUnit的擴(kuò)展版本,用于在Android測(cè)試(androidTest)環(huán)境下執(zhí)行單元測(cè)試,版本為1.1.3,// 它提供了一些針對(duì)Android平臺(tái)的測(cè)試功能擴(kuò)展,便于在Android設(shè)備或模擬器上進(jìn)行更貼合實(shí)際情況的測(cè)試androidTestImplementation 'androidx.test.ext:junit:1.1.3'// 引入Espresso測(cè)試框架,版本為3.4.0,用于在Android測(cè)試(androidTest)環(huán)境下編寫和執(zhí)行UI相關(guān)的測(cè)試用例,// 可以方便地對(duì)Android應(yīng)用的用戶界面進(jìn)行功能測(cè)試,例如模擬用戶點(diǎn)擊、輸入等操作來(lái)驗(yàn)證界面交互的正確性androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
在業(yè)務(wù)層中這樣引用即可。
引入到主工程、功能層、基礎(chǔ)層module
主工程:build.gradle中只需要引入兩行代碼:
apply plugin: 'com.android.application'
apply from: "${rootProject.rootDir}/config_build.gradle"
功能層,基礎(chǔ)層:build.gradle中也只需要引入兩行代碼:
apply plugin: 'com.android.library'apply from: "${rootProject.rootDir}/config_build.gradle"
注意:注意對(duì)比原始配置和抽離出來(lái)的通用gradle文件的區(qū)別,將特有的自行添加的特定的module。
在build.gradle中導(dǎo)入config.gradle
apply from:"config.gradle
Base基礎(chǔ)層:
建立一個(gè)libBase模塊
修改libbase的builde.gradle
我們創(chuàng)建的library模塊會(huì)自動(dòng)設(shè)置啟動(dòng)模式為apply plugin: 'com.android.library'
,這樣基礎(chǔ)模塊就會(huì)被打包成一個(gè)arr文件,配合其他的業(yè)務(wù)模塊application使用。
// 應(yīng)用'com.android.library'插件,將當(dāng)前模塊配置為一個(gè)Android庫(kù)模塊,
// 意味著這個(gè)模塊可以被其他Android模塊依賴使用,而不是作為一個(gè)獨(dú)立可運(yùn)行的應(yīng)用程序
apply plugin: 'com.android.library'// 簡(jiǎn)化手寫,rootProject.ext的次數(shù),提高性能
// 通過(guò)將rootProject.ext賦值給cfg變量,后續(xù)可以更方便地訪問(wèn)根項(xiàng)目中定義的擴(kuò)展屬性,避免多次重復(fù)書寫rootProject.ext,提高代碼可讀性和編寫效率
def cfg = rootProject.extandroid {// 命名空間,從根項(xiàng)目擴(kuò)展屬性(cfg)中獲取applicationId.net作為當(dāng)前模塊的命名空間。// 命名空間用于在Android系統(tǒng)中唯一標(biāo)識(shí)該庫(kù)模塊,類似于包名的作用,方便在不同模塊間區(qū)分和引用namespace cfg.applicationId.net// 編譯項(xiàng)目所使用的SDK版本,從根項(xiàng)目擴(kuò)展屬性(cfg)的android.compileSdkVersion屬性獲取具體的版本號(hào),// 該屬性應(yīng)該在根項(xiàng)目中提前定義好,這樣便于統(tǒng)一管理和修改編譯所依賴的SDK版本compileSdkVersion cfg.android.compileSdkVersiondefaultConfig {// 定義該庫(kù)模塊支持的最低Android系統(tǒng)版本,從根項(xiàng)目擴(kuò)展屬性(cfg)的android.minSdkVersion屬性獲取相應(yīng)數(shù)值,// 這決定了該庫(kù)能在哪些版本的Android系統(tǒng)上被使用,避免在過(guò)低版本系統(tǒng)上出現(xiàn)兼容性問(wèn)題minSdkVersion cfg.android.minSdkVersion// 定義該庫(kù)模塊的目標(biāo)Android系統(tǒng)版本,即主要針對(duì)該版本進(jìn)行功能優(yōu)化和測(cè)試,從cfg.android.targetSdkVersion獲取,// 表示開(kāi)發(fā)過(guò)程中重點(diǎn)考慮該目標(biāo)版本下的功能表現(xiàn)和兼容性targetSdkVersion cfg.android.targetSdkVersion// 指定用于運(yùn)行Android測(cè)試用例的測(cè)試運(yùn)行器,這里使用的是AndroidJUnitRunner,// 它是Android測(cè)試框架中常用的運(yùn)行器,方便編寫和執(zhí)行單元測(cè)試等測(cè)試任務(wù)testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {// 是否啟用代碼壓縮和混淆,設(shè)置為false表示在生成發(fā)布版本(release)時(shí)不進(jìn)行代碼壓縮和混淆操作。// 如果設(shè)置為true,則會(huì)根據(jù)下面指定的proguardFiles進(jìn)行代碼的壓縮和混淆處理minifyEnabled false// 指定Proguard(代碼混淆工具)的配置文件,// 第一個(gè)文件是Android SDK自帶的默認(rèn)優(yōu)化配置文件,第二個(gè)是項(xiàng)目自定義的規(guī)則文件,// 兩者結(jié)合起來(lái)用于確定具體的代碼混淆規(guī)則和方式proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {// 指定項(xiàng)目源代碼兼容的Java版本,這里設(shè)置為Java 8版本,意味著可以在項(xiàng)目中使用Java 8的語(yǔ)法特性進(jìn)行編碼sourceCompatibility JavaVersion.VERSION_1_8// 指定項(xiàng)目編譯生成的字節(jié)碼兼容的Java版本,同樣設(shè)置為Java 8,確保生成的字節(jié)碼能在Java 8及以上的運(yùn)行環(huán)境正常運(yùn)行targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {// 將cfg.library.appcompat對(duì)應(yīng)的庫(kù)以api依賴的方式引入。使用api依賴意味著該庫(kù)不僅會(huì)在當(dāng)前模塊中使用,// 而且當(dāng)其他模塊依賴當(dāng)前模塊時(shí),這個(gè)庫(kù)也會(huì)被傳遞依賴過(guò)去,適用于需要暴露給外部模塊使用的依賴api cfg.library.appcompat// 同理,將cfg.library.material對(duì)應(yīng)的庫(kù)以api依賴的方式引入,方便在模塊中使用符合Material Design規(guī)范的UI組件和樣式等功能,// 并可傳遞給依賴當(dāng)前模塊的其他模塊api cfg.library.material// 將cfg.library.constraintlayout對(duì)應(yīng)的庫(kù)以api依賴的方式引入,用于布局相關(guān)的功能支持,同樣可傳遞給外部依賴模塊api cfg.library.constraintlayout// 將cfg.libGson對(duì)應(yīng)的庫(kù)以api依賴的方式引入,推測(cè)這里的庫(kù)可能是用于處理JSON數(shù)據(jù)的Gson庫(kù),同樣可對(duì)外傳遞依賴api cfg.libGson// 也可以使用這樣的方式一行代碼完成:,相當(dāng)于一個(gè)for循環(huán)遍歷library// 下面這行代碼會(huì)遍歷cfg.library中的每個(gè)鍵值對(duì)(k表示鍵,v表示值),并將每個(gè)值以implementation依賴的方式引入。// implementation依賴表示該庫(kù)僅在當(dāng)前模塊內(nèi)部使用,不會(huì)傳遞給依賴當(dāng)前模塊的其他模塊library.each { k, v -> implementation v }// 引入JUnit測(cè)試框架,版本為4.13.2,用于編寫和執(zhí)行單元測(cè)試,這里是在普通測(cè)試(test)環(huán)境下使用的依賴testImplementation 'junit:junit:4.13.2'// 引入JUnit的擴(kuò)展版本,用于在Android測(cè)試(androidTest)環(huán)境下執(zhí)行單元測(cè)試,版本為1.1.5,// 它提供了一些針對(duì)Android平臺(tái)的測(cè)試功能擴(kuò)展androidTestImplementation 'androidx.test.ext:junit:1.1.5'// 引入Espresso測(cè)試框架,版本為3.5.1,用于在Android測(cè)試(androidTest)環(huán)境下編寫和執(zhí)行UI相關(guān)的測(cè)試用例,// 方便對(duì)Android應(yīng)用的用戶界面進(jìn)行功能測(cè)試androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
你可以先不管這些什么rootProject.ext.android.minSdk,解釋一下,在 Gradle 中,rootProject 是指項(xiàng)目的根項(xiàng)目,即頂層項(xiàng)目。 ext 是 ExtraPropertiesExtension 的縮寫,是一個(gè)擴(kuò)展屬性的機(jī)制。通過(guò)將屬性添加到 rootProject.ext,你可以在整個(gè) Gradle 構(gòu)建中共享這些屬性。相當(dāng)于一個(gè)全局變量。
組件層(業(yè)務(wù))
建立一個(gè)login組件模塊
這里不介紹了,網(wǎng)上的使用挺多的,依照網(wǎng)上的來(lái)就很簡(jiǎn)單了
修改login的builde.gradle
將涉及到共用部分的寫成ext的形式。
1.引入config_build文件
//動(dòng)態(tài)切換集成\組件模式
if (rootProject.ext.isDebug) {apply plugin: 'com.android.application'
} else {apply plugin: 'com.android.library'
}apply from: "${rootProject.rootDir}/config_build.gradle"android {// 業(yè)務(wù)組件特定的配置namespace rootProject.ext.applicationId.maindefaultConfig {//組件模式需要applicationIdif (rootProject.ext.isDebug) {applicationId rootProject.ext.applicationId.main}}//動(dòng)態(tài)切換集成/組件模式的AndroidManifestsourceSets {main {if (rootProject.ext.isDebug) {manifest.srcFile 'src/main/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/main/AndroidManifest.xml'}}}
}dependencies {// 業(yè)務(wù)組件特定的依賴配置}
2.不引入
//判斷屬于打包模式還是調(diào)試模式
if (rootProject.ext.isDebug) {apply plugin: 'com.android.application'
} else {apply plugin: 'com.android.library'
}def cfg = rootProject.extandroid {namespace cfg.applicationId.logincompileSdkVersion cfg.android.compileSdkVersiondefaultConfig {//判斷如果是調(diào)試模式則需要當(dāng)做一個(gè)application啟動(dòng),則需要一個(gè)yif (cfg.isDebug) {applicationId cfg.applicationId.login}minSdkVersion cfg.android.minSdkVersiontargetSdkVersion cfg.android.targetSdkVersionversionCode cfg.android.versionCodeversionName cfg.android.versionNametestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}//選擇合適的manifestsourceSets {main {if (cfg.isDebug) {manifest.srcFile 'src/main/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/main/AndroidManifest.xml'//注意我們還需在正式環(huán)境下屏蔽Debug包下的所有文件java{exclude "**/debug/**"}}}}}dependencies {//導(dǎo)入基礎(chǔ)模塊implementation project(':modulesBase:libBase')testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit:1.1.5'androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
解釋:
if (rootProject.ext.isDebug) {apply plugin: 'com.android.application'
} else {apply plugin: 'com.android.library'
}
這一部分就不解釋了哈,從下面解釋
sourceSets 定義了一個(gè) main 源集。
對(duì)于 main 源集,使用了一個(gè)條件語(yǔ)句(if (cfg.isDebug))來(lái)決定使用哪個(gè)清單文件。
“/debug/”: 這是一個(gè) Ant 風(fēng)格的通配符。** 表示匹配任意數(shù)量的目錄,因此 /debug/ 表示匹配任何包含 “debug” 目錄的路徑。
sourceSets {main {if (cfg.isDebug) {manifest.srcFile 'src/main/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/main/AndroidManifest.xml'//注意我們還需在正式環(huán)境下屏蔽Debug包下的所有文件java{exclude "**/debug/**"}}}}
然后在dependencies中導(dǎo)入了剛才的libBase模塊,此時(shí)login就具有了libBase所存在的依賴。
implementation project(':modulesBase:libBase')
app層:
修改App的build.gradle
基本和剛才login組件的修改方法相似,plugins不用改動(dòng),因?yàn)锳pp層不會(huì)拿來(lái)當(dāng)作library。
plugins {id 'com.android.application'
}
需要注意的就是dependencies。同樣的app也需要導(dǎo)入基礎(chǔ)模塊的依賴,并且app是關(guān)聯(lián)其他的多個(gè)組件,這里還需要導(dǎo)入其他組件例如:login
因此在這里也需要判斷是否是debug模式,如果是debug模式就不需要導(dǎo)入這些組件。
plugins {id 'com.android.application'
}def cfg = rootProject.extandroid {namespace cfg.applicationId.appcompileSdkVersion cfg.android.compileSdkVersiondefaultConfig {applicationId cfg.applicationId.appminSdkVersion cfg.android.minSdkVersiontargetSdkVersion cfg.android.targetSdkVersionversionCode cfg.android.versionCodeversionName cfg.android.versionNametestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"//讓java代碼也可以使用isDebugbuildConfigField("boolean","isDebug",String.valueOf(isDebug))}//啟用buildConfigField功能buildFeatures {buildConfig true}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation project(':modulesBase:libBase')//如果不是Debug的情況下則導(dǎo)入各個(gè)組件的模塊if (!cfg.isDebug){implementation project(":modulesCore:live")implementation project(":modulesCore:login")}testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit:1.1.5'androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
如上即可。
config_build文件的作用其實(shí)就是濃縮了一下,簡(jiǎn)化一點(diǎn)點(diǎn)代碼Gradle基礎(chǔ)