主頁 > 移動端開發 > 組件化下如何優雅進行本地除錯,即aar依賴與module依賴動態切換

組件化下如何優雅進行本地除錯,即aar依賴與module依賴動態切換

2021-09-07 08:36:21 移動端開發

在組件化開發的時候,會面臨的一個問題就是組件的除錯,

即組件和主工程不在同一個工程目錄下,主工程對組件的依賴,是通過依賴組件發布的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')
                }
            }
        }
    }
})
  1. 給 gradle 物件,增加 ProjectEvaluationListener 監聽事件
  2. 在 ProjectEvaluationListener 的 beforeEvaluate 方法中,增加一些組件需要依賴的額外配置,如果沒有,可以不用添加,
  3. 在 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

標籤:其他

上一篇:初識 Jetpack Compose(二) :布局

下一篇:刷到就是賺到!八月阿里 Android 高級崗面經新鮮出爐(年薪百萬)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more