在組件化開發的時候,會面臨的一個問題就是組件的除錯,
即組件和主工程不在同一個工程目錄下,主工程對組件的依賴,是通過依賴組件發布的aar包的方式引入,當組件開發了新的功能,就會發布一個新的 aar 包,并在主工程引入,
但如果這種方式帶來的問題就是,如果組件有bug或者需要除錯的時候,就會帶來不便,具體來說就是,如果改一個問題,就發布一個組件的 aar 包,然后在主工程驗證問題是否被修復成功, 這樣就會頻繁的發布 aar 包,而且除錯的效率也低,那有沒有辦法在開發階段,直接參考 組件module,而不使用組件的 aar 包呢?答案當然是有的,下面就來介紹一下具體的實作方案,
準備作業:
假設主工程路徑:/Users/mei/WorkSpace/AndroidProjects/TestModuleDep
組件工程路徑:/Users/mei/WorkSpace/AndroidProjects/module-user/user
組件的maven路徑:com.mei.module:user:1.0.0
在主工程的 build.gradle 檔案中,引入 user 組件:
dependencies {
implementation 'com.mei.module:user:1.0.0'
}
一、組件module(原始碼)依賴方式
從上面的介紹可以知道,主工程 依賴 user 組件,是通過依賴 user 組件的 aar 包的方式進行的,如果想本地除錯的話,可以改成依賴組件module 的方式,具體操作如下:
1、include 組件 module
在主工程的 settings.gradle 檔案中,把 組件module 加入編譯,即 include 組件module,組件跟主工程不在同一個工程目錄下,所以,組件module 的 include 方式也有所不同:
include ":user"
project(":user").projectDir = file("/Users/mei/WorkSpace/AndroidProjects/module-user/user")
如上代碼所示,在 主工程的 settings.gradle 檔案中,增加上述代碼,就可以把 組件module 以 include 的方式,加入到主工程中,
2、依賴組件module
在主工程的 app module 中,依賴組件module,即在 app 的 build.gradle 檔案中,依賴組件module,同時,把組件的 aar 包依賴給注釋掉:
dependencies {
// implementation 'com.mei.module:user:1.0.0'
implementation project(':user') // 以 組件module 的方式依賴組件
}
經過上面兩步操作,就可以直接依賴組件的原始碼,而不是組件的 aar 包了,除錯起來就非常方便了,不用每次改動都發布一個aar 包,
通過上面的方式,是可以原始碼依賴的問題,但每次需要除錯的時候都這樣去改的話,就顯得非常的麻煩,還需要把 aar 依賴的方式給注釋掉,萬一不小心提交了代碼,就有可能導致遠程無法打包的問題,
那有沒有什么方式是在 開發的時候使用 module 依賴,而不改變app 的gradle 檔案呢?下面就介紹一種 aar依賴 與 原始碼依賴快速切換的方式,
二、aar依賴 與 原始碼依賴 快速切換
在主工程的 build.gradle 檔案中,增加如下代碼:
allprojects {// 所有組件都添加
configurations.all {
resolutionStrategy {
dependencySubstitution {
// module,groupId:artifactId
// project,組件module 名稱
substitute module( "com.mei.module:user") with project(':user')
}
}
}
}
上述代碼的意思是,以 module 代替 aar 包,則在編譯工程的時候,只會把 module 的代碼加入編譯,而 aar 包的代碼不會加入編譯,
當然,也可以只在 app 的build.gradle 檔案中,加入上述代碼,這個時候就可以不用呼叫 allprojects 方法了,如:
configurations.all {
resolutionStrategy {
dependencySubstitution {
// module,groupId:artifactId
// project,組件module 名稱
substitute module( "com.mei.module:user") with project(':user') // 注釋1
}
}
}
如果不想使用 module 依賴,就可以 把 注釋1 的代碼,給注釋掉,就可以接著使用 aar依賴了,
三、組件依賴封裝
經過 二、aar依賴 與 原始碼依賴 快速切換 的操作之后,我們可以不用 注釋掉組件的 aar 依賴,就可以實作 aar依賴 與 module依賴的 快速切換,但還是需要去修改主工程的 settings.gradle 檔案和 build.gradle 檔案,還是會存在誤提交的問題,
如果我把 所有的操作,都放到一個 gradle 檔案中,只在主工程的 settings.gradle 檔案中,引入這個 gradle 檔案,就可以實作上面所有的操作,并且在找不到這個檔案的時候,也不會導致編譯流程失敗,不就可以解決誤提交的問題嗎?
下面就來看看具體是如何封裝的,
1、在 module 工程中,增加 module 依賴檔案
在 module 工程中,增加 user_dependency.gradle 檔案(完整路徑:/Users/mei/WorkSpace/AndroidProjects/module-user/user_dependency.gradle),在這個檔案中,實作 組件module 的 引入和 與aar依賴的動態切換功能,注意,這個檔案可以不用加入到 git 管理,
1-1、組件module 依賴
include ":user"
project(":user").projectDir = file("/Users/mei/WorkSpace/AndroidProjects/module-user/user")
1-2、aar 依賴 與 組件module 依賴的動態切換
在 user_dependency.gradle 檔案中,增加如下監聽:
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
@Override
void beforeEvaluate(Project projectObj) {
try {
// 增加擴展屬性
if (!projectObj.rootProject.extensions.hasProperty("kotlin_version")) {
projectObj.rootProject.extensions.add("kotlin_version", "1.4.32")
}
} catch (Exception e) {
e.printStackTrace()
}
// 應用組件工程的全域組態檔
projectObj.rootProject.apply from: "/Users/mei/WorkSpace/AndroidProjects/module-user/mavenConfig.gradle"
println "beforeEvaluate project.configurations=${projectObj.configurations}"
}
@Override
void afterEvaluate(Project projectObj, ProjectState state) {
println "project name is $projectObj"
println "afterEvaluate project.configurations=${projectObj.configurations}"
if (projectObj.name != "app") {
return
}
// 切換 aar依賴 與 組件module 依賴
projectObj.configurations.all { Configuration ->
resolutionStrategy {
dependencySubstitution {
substitute module( "com.mei.module:user") with project(':user')
}
}
}
}
})
- 給 gradle 物件,增加 ProjectEvaluationListener 監聽事件
- 在 ProjectEvaluationListener 的 beforeEvaluate 方法中,增加一些組件需要依賴的額外配置,如果沒有,可以不用添加,
- 在 ProjectEvaluationListener 的 afterEvaluate 方法中,給指定的工程物件,增加配置資訊,如:給 app 工程,增加動態切換 aar依賴 和 module 依賴的 配置,
注意:
- 要把 afterEvaluate 的 Project 引數重新命名,否則在 dependencySubstitution 閉包中,呼叫 project() 方法會報錯,
- 只能在 ProjectEvaluationListener 的 afterEvaluate 方法 給工程增加配置資訊,因為在 afterEvaluate 方法中,工程的configurations 配置物件不為空,而在 beforeEvaluate 方法中,工程的 configurations 物件是一個空物件,從而也無法 增加配置資訊,
1-3、完整的 user_dependency.gradle 代碼如下:
// 1. include 組件 module ,注意,使用絕對路徑
include ":user"
project(":user").projectDir = file("/Users/mei/WorkSpace/AndroidProjects/module-user/user")
// 2. aar依賴 與 module依賴 動態切換
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
@Override
void beforeEvaluate(Project projectObj) {
try {
// 增加擴展屬性
if (!projectObj.rootProject.extensions.hasProperty("kotlin_version")) {
projectObj.rootProject.extensions.add("kotlin_version", "1.4.32")
}
} catch (Exception e) {
e.printStackTrace()
}
// 應用組件工程的全域組態檔
projectObj.rootProject.apply from: "/Users/mei/WorkSpace/AndroidProjects/module-user/mavenConfig.gradle"
println "beforeEvaluate project.configurations=${projectObj.configurations}"
}
@Override
void afterEvaluate(Project projectObj, ProjectState state) {
println "project name is $projectObj"
println "afterEvaluate project.configurations=${projectObj.configurations}"
if (projectObj.name != "app") {
return
}
// 切換 aar依賴 與 組件module 依賴
projectObj.configurations.all { Configuration ->
resolutionStrategy {
dependencySubstitution {
substitute module( "com.mei.module:user") with project(':user')
}
}
}
}
})
2、在主工程的 settings.gradle 檔案中,應用依賴檔案
在主工程的 settings.gradle 檔案中,應用 user_dependency.gradle 檔案:
include ":app"
try {
apply from:"/Users/mei/WorkSpace/AndroidProjects/module-user/user_dependency.gradle"
} catch (Exception e) {
e.printStackTrace()
}
通過絕對路徑的方式,應用 user_dependency.gradle 檔案,這里增加 try catch 的目的是,即使找不到 user_dependency.gradle 檔案的時候,也不會影響整體的編譯流程,即 哪怕參考不到 組件module 還可以使用 aar 依賴,
這樣,只需要修改主工程的 settings.gradle 檔案,就可以實作 組件 aar依賴 與 組件module 的動態切換,而且 settings.gradle 的修改也可以提交,不會影響線上的的打包流程,
當debug的 時候,如果想用 aar依賴的方式,可以把 應用 user_dependency.gradle 檔案的代碼注釋掉就可以了,
當然,也可以在 user_dependency.gradle 檔案中,增加一個 開關,表示是否使用 module 依賴,從而控制 module 與 aar包 的動態切換操作,
如:
....
def useModule = true
// 2. aar依賴 與 module依賴 動態切換
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
@Override
void beforeEvaluate(Project projectObj) {
....
}
@Override
void afterEvaluate(Project projectObj, ProjectState state) {
if (projectObj.name != "app") {
return
}
// 切換 aar依賴 與 組件module 依賴
projectObj.configurations.all { Configuration ->
resolutionStrategy {
dependencySubstitution {
if(useModule){ // 只有開關打開的時候,才使用 module 依賴
substitute module( "com.mei.module:user") with project(':user')
}
}
}
}
}
})
思考與擴展:
上面的操作,是否可以封裝到一個插件中,這樣只需要在 主工程中 提供一份 配置資訊,就可以動態控制 aar依賴 與 組件module 依賴的動態切換,本地除錯也會更加的方便快捷,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/298145.html
標籤:其他
