摘要:如果你有新建一個(gè)項(xiàng)目的經(jīng)歷,那么你將看到推薦的方案在的中使用來(lái)定義版本號(hào)全局變量。例如之前的版本號(hào)就可以使用如下方式實(shí)現(xiàn)因?yàn)槭褂玫氖钦Z(yǔ)言,所以以上都是語(yǔ)法例如版本控制,上面代碼的意思就是將有個(gè)相關(guān)的版本依賴放到的變量中,同時(shí)放到了中。
上篇文章我們已經(jīng)將Gradle基礎(chǔ)運(yùn)用介紹了一遍,可以這么說(shuō),只要你一直看了我這個(gè)Gradle系列,那么你的Gradle也將過(guò)關(guān)了,應(yīng)對(duì)正常的工作開(kāi)發(fā)已經(jīng)不成問(wèn)題了。
這篇文章我要向你介紹的是關(guān)于如何使用Gradle來(lái)更加優(yōu)雅的管理多個(gè)module之間的依賴關(guān)系。
相信你一定有這樣的經(jīng)歷:主項(xiàng)目依賴于多個(gè)子項(xiàng)目,或者項(xiàng)目間互相依賴。不同子項(xiàng)目間的依賴的第三方庫(kù)版本又沒(méi)有進(jìn)行統(tǒng)一,升級(jí)一個(gè)版本所有依賴的項(xiàng)目都要進(jìn)行修改;甚至minSdkVersion與targetSdkVersion也不相同。
今天我們就來(lái)解決這個(gè)問(wèn)題,讓Gradle版本管理更加優(yōu)雅。
Google推薦之前的文章Android Gradle系列-運(yùn)用篇中的dependencies使用的是最基本的引用方式。如果你有新建一個(gè)kotlin項(xiàng)目的經(jīng)歷,那么你將看到Google推薦的方案
buildscript { ext.kotlin_version = "1.1.51" repositories { google() jcenter() } dependencies { classpath "com.android.tools.build:gradle:3.0.0" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } }
在rootProject的build.gradle中使用ext來(lái)定義版本號(hào)全局變量。這樣我們就可以在module的build.gradle中直接引用這些定義的變量。引用方式如下:
dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" }
你可以將這些變量理解為java的靜態(tài)變量。通過(guò)這種方式能夠達(dá)到不同module中的配置統(tǒng)一,但局限性是,一但配置項(xiàng)過(guò)多,所有的配置都將寫(xiě)到rootProject項(xiàng)目的build.gradle中,導(dǎo)致build.gradle臃腫。這不符合我們的所提倡的模塊開(kāi)發(fā),所以應(yīng)該想辦法將ext的配置多帶帶分離出來(lái)。
這個(gè)時(shí)候我就要用到之前的文章Android Gradle系列-原理篇中所介紹的apply函數(shù)。之前的文章我們只使用了apply三種情況之一的plugin(應(yīng)用一個(gè)插件,通過(guò)id或者class名),只使用在子項(xiàng)目的build.gradle中。
apply plugin: "com.android.application"
這次我們需要使用它的from,它主要是的作用是應(yīng)用一個(gè)腳本文件。作用接下來(lái)我們需要做的是將ext配置多帶帶放到一個(gè)gradle腳本文件中。
首先我們?cè)趓ootProject目錄下創(chuàng)建一個(gè)gradle腳本文件,我這里取名為version.gradle。
然后我們?cè)趘ersion.gradle文件中使用ext來(lái)定義變量。例如之前的kotlin版本號(hào)就可以使用如下方式實(shí)現(xiàn)
ext.deps = [:] def versions = [:] versions.support = "26.1.0" versions.kotlin = "1.2.51" versions.gradle = "3.2.1" def support = [:] support.app_compat = "com.android.support:appcompat-v7:$versions.support" support.recyclerview = "com.android.support:recyclerview-v7:$versions.support" deps.support = support def kotlin = [:] kotlin.kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jre7:$versions.kotlin" kotlin.plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin" deps.kotlin = kotlin deps.gradle_plugin = "com.android.tools.build:gradle:$versions.gradle" ext.deps = deps def build_versions = [:] build_versions.target_sdk = 26 build_versions.min_sdk = 16 build_versions.build_tools = "28.0.3" ext.build_versions = build_versions def addRepos(RepositoryHandler handler) { handler.google() handler.jcenter() handler.maven { url "https://oss.sonatype.org/content/repositories/snapshots" } } ext.addRepos = this.&addRepos
因?yàn)間radle使用的是groovy語(yǔ)言,所以以上都是groovy語(yǔ)法
例如kotlin版本控制,上面代碼的意思就是將有個(gè)kotlin相關(guān)的版本依賴放到deps的kotlin變量中,同時(shí)deps放到了ext中。其它的亦是如此。
既然定義好了,現(xiàn)在我們開(kāi)始引入到項(xiàng)目中,為了讓所有的子項(xiàng)目都能夠訪問(wèn)到,我們使用apply from將其引入到rootProject的build.gradle中
buildscript { apply from: "versions.gradle" addRepos(repositories) dependencies { classpath deps.gradle_plugin classpath deps.kotlin.plugin } }
這時(shí)build.gradle中就默認(rèn)有了ext所聲明的變量,使用方式就如dependencies中的引用一樣。
我們?cè)倏瓷厦娴腶ddRepos方法,在關(guān)于Gradle原理的文章中已經(jīng)分析了repositories會(huì)通過(guò)RepositoryHandler來(lái)執(zhí)行,所以這里我們直接定義一個(gè)方法來(lái)統(tǒng)一調(diào)用RepositoryHandler。這樣我們?cè)赽uild.gradle中就無(wú)需使用如下方式,直接調(diào)用addRepos方法即可
//之前調(diào)用 repositories { google() jcenter() } //現(xiàn)在調(diào)用 addRepos(repositories)
另一方面,如果有多個(gè)module,例如有module1,現(xiàn)在就可以直接在module1中的build.gradle中使用定義好的配置
dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) // support implementation deps.support.app_compat //kotlin implementation deps.kotlin.kotlin_stdlib }
上面我們還定義了sdk與tools版本,所以也可以一起統(tǒng)一使用,效果如下
android { compileSdkVersion build_versions.target_sdk buildToolsVersion build_versions.build_tools defaultConfig { applicationId "com.idisfkj.androidapianalysis" minSdkVersion build_versions.min_sdk targetSdkVersion build_versions.target_sdk versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } ... }
一旦實(shí)現(xiàn)了統(tǒng)一配置,那么之后我們要修改相關(guān)的版本就只需在我們定義的version.gradle中修改即可。無(wú)需再對(duì)所用的module進(jìn)行逐一修改與統(tǒng)一配置。
BuildSrc&Kotlin如果你的項(xiàng)目使用了kotlin,那么buildSrc&Kotlin的統(tǒng)一管理方案將更適合你。
Gradle項(xiàng)目會(huì)默認(rèn)識(shí)別buildSrc目錄,并且會(huì)將該目錄中的配置注入到build.gradle中,以至于讓build.gradle能夠直接引用buildSrc中的配置項(xiàng)。
有了這一特性,我們就可以直接將之前version.gradle中的配置放入到buildSrc中,下面我們開(kāi)始實(shí)現(xiàn)。
首先在根目錄新建一個(gè)buildSrc目錄(與app同級(jí)),然后在該目錄新建src/main/java目錄,該目錄是你之后配置項(xiàng)所在的目錄;同時(shí)再新建build.gradle.kts文件,并在該文件中添加kotlin-dsl
plugins { `kotlin-dsl` } repositories { jcenter() }
之后再sync project,最終的目錄結(jié)構(gòu)如下
搭建好了目錄,現(xiàn)在我們?cè)趕rc/main/java下使用kotlin新建Dependencies文件(文件名任意),在該文件中將之前的配置項(xiàng)放進(jìn)來(lái),只是使用kotlin語(yǔ)法進(jìn)行實(shí)現(xiàn)而已,轉(zhuǎn)化的代碼如下
object Versions { const val support = "26.1.0" const val kotlin = "1.3.31" const val gradle = "3.4.1" const val target_sdk = 26 const val min_sdk = 16 const val build_tools = "28.0.3" } object Dependencies { val app_compat = "com.android.support:appcompat-v7:${Versions.support}" val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}" val kotlin_plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}" val gradle_plugin = "com.android.tools.build:gradle:${Versions.gradle}" val addRepos: (handler: RepositoryHandler) -> Unit = { it.google() it.jcenter() it.maven { url = URI("https://oss.sonatype.org/content/repositories/snapshots") } } }
這時(shí)你就可以直接使用Dependencies與Versions在各個(gè)build.gradle中引用,例如app下的build.gradle
android { compileSdkVersion Versions.target_sdk buildToolsVersion Versions.build_tools defaultConfig { applicationId "com.idisfkj.androidapianalysis" minSdkVersion Versions.min_sdk targetSdkVersion Versions.target_sdk versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } ... } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) // support implementation Dependencies.app_compat //kotlin implementation Dependencies.kotlin_stdlib }
根目錄的build.gradle亦是如此
buildscript { Dependencies.addRepos.invoke(repositories) dependencies { classpath Dependencies.gradle_plugin classpath Dependencies.kotlin_plugin } } allprojects { Dependencies.addRepos.invoke(repositories) } task clean(type: Delete) { delete rootProject.buildDir }
其實(shí)我們真正需要get到的是一種思想,將配置統(tǒng)一管理。至于到底使用哪一種,這就看個(gè)人喜好了,但如果你的項(xiàng)目使用了kotlin,我還是建議你使用buildSrc模式,因?yàn)閷?duì)于Groovy語(yǔ)法而言,我相信你還是對(duì)Kotlin更加熟悉。
源碼地址: https://github.com/idisfkj/an...
如果想了解更多關(guān)于我的文章,可以掃描下方二維碼,關(guān)注我的公眾號(hào)~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/74917.html
閱讀 3046·2023-04-26 02:27
閱讀 2763·2021-11-22 13:54
閱讀 902·2021-11-12 10:36
閱讀 3753·2021-10-09 09:44
閱讀 3178·2021-10-09 09:41
閱讀 1223·2021-09-22 10:02
閱讀 2833·2019-08-30 15:56
閱讀 3106·2019-08-30 11:02