原文地址: https://www.jianshu.com/p/f671dd76868f
-
0 前言
- 0.1 起源
- 0.2 元件化方案分析
- 0.2.1 業務元件的劃分和程式碼隔離
- 0.2.2 路由框架
- 0.2.3 基礎庫
- 0.3 ArmsComponent 的優勢
-
1 簡介
- 1.1 什麼是元件化?
- 1.2 為什麼要元件化?
- 1.3 分析現有的元件化方案
- 1.4 如何選擇元件化方案?
-
2 元件化方案描述
-
3 專案講解
- 3.1 如何讓元件獨立執行?
- 3.2 配置 AndroidManifest
- 3.3 配置 ConfigModule
- 3.4 RouterHub
- 3.5 EventBusHub
- 3.6 在專案中使用多個不同的域名
0 前言
MVPArms 從兩年前開源至今, 已經累積了 5k star, 獲得了上千個商業專案的信賴和認可
回顧兩年前, 那時 MVPArms 還沒誕生, MVP、Dagger2、Rxjava、Retrofit 這些技術在國內才剛剛開始流行, 在網上能搜尋到的中文學習資料遠沒有現在這麼豐富, 特別是 Dagger, 在網上能搜尋到的文章甚至有很多講的是 Square 的 Dagger1, 學習資料的匱乏加上 Dagger2 本身就是塊硬骨頭, 讓本人在學習的道路上不知道多走了多少彎路
從那時開始, 讓初學者都能夠快速搭建一個 MVP + Dagger2 + Retrofit + Rxjava 專案的種子就已經深埋在心中, 後面經過不懈的努力, MVPArms 終於誕生並開源了, 開源以後只是一直堅持將 程式碼, 註釋 和 文件 做到極致, 沒想到的是, MVPArms 能發展到如今的體量, 感謝開源!
0.1 起源
這是 MVPArms 的起源, ArmsComponent 的起源同樣相似, 從去年開始, 元件化逐漸火熱起來, 本人也在去年年初開始在公司專案中進行元件化, 一切還算順利
那時同樣的種子繼續埋在了心中, 我想讓剛剛接觸元件化的初學者也能快速搭建一箇中小型的元件化專案, 經過一年的不斷優化, 終於決定將其開源(MVPArms 官方元件化方案 ArmsComponent)
Github : 您的 Star 是我堅持的動力 ✊
0.2 元件化方案分析
看了很多元件化方案, 所以總結了在元件化中很重要的三個大點:
- 基礎庫(網路請求、圖片載入等)的封裝
- 路由框架(頁面跳轉, 服務提供)
- 業務元件的劃分和程式碼隔離
0.2.1 業務元件的劃分和程式碼隔離
先說第三點 業務元件的劃分和程式碼隔離, 現在大部分的文章都圍繞著這點, 我這裡發表下個人的觀點, 第三點確實是很重要的一點, 不管是大廠的方案還是小廠的方案都有借鑑之處, 但是這點也是最不可能討論出最終結果和統一解決方案的一點
每個公司、每個專案的情況都不一樣, 大廠的方案真的適合您嗎? 不一定, 大廠幾十個業務群, 幾百號開發人員, 他們的組織結構和專案規模都不是普通公司能比擬的, 如果伸拉硬套他們的方案, 進行更嚴格更細粒度的程式碼隔離, 可能產出的價值還不及您先前付出的代價, 帶來效率的降低, 所以根據專案的實際情況做出靈活的調整才是專案負責人最應該乾的事, 這點我在後面會有詳細的介紹
0.2.2 路由框架
陸續也有很多元件化方案開源自己的 路由框架, 是個很不錯的開始, 我覺得大家寫的都不錯, 各有各的優勢, 本方案也決定用別人的 路由框架, 自己寫的原理也差不多, 還不一定比別人考慮的完善, 還要自己維護, 為什麼不選擇一個成熟穩定的呢?
0.2.3 基礎庫
很多元件化文章只是在講如何拆分以及封裝基礎庫, 但是至今沒看到有哪個元件化方案開源過完整的基礎庫的, 我猜測原因可能是, 元件化方案都是從商業專案不斷的業務迭代中逐漸完善的, 基礎庫也屬於公司的核心機密, 所以不可能開源
但是基礎庫尤其重要, 特別是相容元件化的基礎庫, 這關乎到元件化方案的根基, 根基都沒有, 何談其他更高階的功能? 但是從封裝到完善一個相容元件化的基礎庫是需要很長時間的, 大多數中小公司是不願意投入這個成本的
0.3 ArmsComponent 的優勢
ArmsComponent 擁有一鍵自動生成元件功能, 可以一鍵搭建整體元件架構, 讓您體驗純傻瓜式的元件化開發, 雖然一鍵搭建功能讓新手也可以一秒開始元件化專案, 但本方案還是提供有上萬字的詳細文件讓您可以更深入的瞭解本方案, 並且 JessYan 鄭重承諾, ArmsComponent 將和 MVPArms 一起持續維護下去, ArmsComponent 絕對是一個真正用心對待的元件化方案
MVPArms 是一個開源兩年, 成熟穩定, 涵蓋大量主流技術且相容元件化的基礎庫, MVPArms 使得 ArmsComponent 成為了唯一提供完整基礎庫的元件化方案, 這就是 ArmsComponent 相對於其他元件化方案最大的優勢
因為有了 基礎庫 的存在, 再加上已有的 路由框架, 元件化中的三個大點就已經佔有兩個(業務元件的劃分和程式碼隔離 在後面會有介紹), 因此使用 ArmsComponent 啟動一個新專案, 即可快速進行元件化, 將 Demo (元件化專案雛形) 克隆下來後, 稍作修改, 馬上就可以投入到業務的開發之中
ArmsComponent 對於新專案以及已經開始使用 MVPArms 的專案將會更加便捷, 有著優於其他元件化方案的體驗, 對於那些網路請求, 圖片載入等基礎功能亂七八糟散落到專案各處, 沒有統一抽離出來的舊專案, 建議直接使用 MVPArms, 開始元件化
如果您不想使用 MVPArms, 覺得接入成本太大, 沒關係, 借鑑下 MVPArms 和 ArmsComponent 的程式碼, 嘗試改造自己的專案, 也是個不錯的選擇
1 簡介
好了, 進入正題!
1.1 什麼是元件化?
元件化簡單概括就是把一個功能完整的 App 或模組拆分成多個子模組, 每個子模組可以獨立編譯和執行, 也可以任意組合成另一個新的 App 或模組, 每個模組即不相互依賴但又可以相互互動, 遇到某些特殊情況甚至可以升級或者降級
1.2 為什麼要元件化?
現在的專案隨著需求的增加規模變得越來越大, 規模的增大帶來了很多煩惱, 各種業務錯中複雜的交織在一起, 每個業務模組之間, 程式碼沒有約束, 帶來了程式碼邊界的模糊, 程式碼衝突時有發生, 更改一個小問題可能引起一些新的問題, 牽一髮而動全身, 增加一個新需求, 瞻前顧後的熟悉了大量前輩們寫的程式碼後才敢動手, 編譯時間也不在斷增加, 開發效率極度的下降, 在這種情況下元件化的出現就是為了解決以上的煩惱
1.3 分析現有的元件化方案
很多大廠的元件化方案是以 多工程 + 多 Module 的結構(微信, 美團等超級 App 更是以 多工程 + 多 Module + 多 P 工程(以頁面為單元的程式碼隔離方式) 的三級工程結構), 使用 Git Submodule 建立多個子倉庫管理各個模組的程式碼, 並將各個模組的程式碼打包成 AAR 上傳至私有 Maven 倉庫使用遠端版本號依賴的方式進行模組間程式碼的隔離
1.4 如何選擇元件化方案?
按照康威定律, 系統架構的設計需要根據組織間的溝通結構, 因為現在大部分專案的規模和開發人員的數量以及結構還不足以需要某些大廠釋出的元件化方案支撐(大廠的組織結構和專案規模都非常龐大, 他們的方案不一定完全適合所有公司的專案), 進行更嚴格更細粒度的程式碼間以及模組間的隔離, 盲目的使用某些元件化方案, 可能會帶來開發效率降低, 開發成本遠大於收益等情況, 價效比變低, 作為專案負責人, 應該根據專案目前的規模以及開發人員的組織結構去選擇目前最適合的元件化方案, 做到以專案實際情況去制定技術方案, 而不是盲目跟隨某些大廠的技術方案讓專案和開發人員花費大量時間去調整和適應
2 元件化方案描述
ArmsComponent 目前採用的是 單工程 + 多 Module 的結構, 由於 Demo 較小僅僅為了展示基本規範, 所以也只是採用原始碼依賴並沒有做到遠端版本號依賴元件, 程式碼管理也只是採用 單倉庫 + 多分支 的方式, 這樣也是對於開發初期, 專案規模還較小, 開發人員也較少時, 開發效率較高的方案, 如果您的專案規模較大, 開發人員眾多, 就可以採用上面提到的 多工程 + 多 Module, 並使用私有 Maven 倉庫管理元件版本
世界上沒有一個方案可以完美到兼顧所有情況, 並且還滿足所有人, 所有專案的需求, 所以專案負責人必須按照專案實際情況做出靈活的調整, 才能做出最適合自家專案的方案
2.1 架構圖一覽
ArmsComponent 元件化架構圖
2.2 架構圖詳解
目前架構一共分為三層, 從低到高依次是基礎層, 業務層和宿主層, 由於目前專案較小人員較少所以三層都集中在一個工程中, 但您可以根據專案的規模和開發人員的數量拆分成多個工程協同開發
2.2.1 宿主層
宿主層位於最上層, 主要作用是作為一個 App 殼, 將需要的模組組裝成一個完整的 App, 這一層可以管理整個 App 的生命週期(比如 Application 的初始化和各種元件以及三方庫的初始化)
2.2.2 業務層
業務層位於中層, 裡面主要是根據業務需求和應用場景拆分過後的業務模組, 每個模組之間互不依賴, 但又可以相互互動, 比如一個商城 App 由 搜尋, 訂單, 購物車, 支付 等業務模組組成
Tips: 每個業務模組都可以擁有自己獨有的 SDK 依賴和自己獨有的 UI 資源 (如果是其他業務模組都可以通用的 SDK 依賴 和 UI 資源 就可以將它們抽離到 基礎 SDK(CommonSDK 2.2.3.3) 和 UI 元件(CommonRes 2.2.3.3.2) 中)
2.2.2.1 業務模組的拆分
寫業務之前先不要急著動手敲碼, 應該先根據初期的產品需求到後期的運營規劃結合起來清晰的梳理一下業務在未來可能會發生的發展, 確定業務之間的邊界, 以及可能會發生的變化, 最後再確定下來真正需要拆分出來的業務模組再進行拆分
2.2.3 基礎層
基礎層位於最底層, 裡面又包括 核心基礎業務模組、公共服務模組、 基礎 SDK 模組, 核心基礎業務模組 和 公共服務模組 主要為業務層的每個模組服務, 基礎 SDK 模組 含有各種功能強大的團隊自行封裝的 SDK 以及第三方 SDK, 為整個平臺的基礎設施建設提供動力
2.2.3.1 核心基礎業務
核心基礎業務 為 業務層 的每個業務模組提供一些與業務有關的基礎服務, 比如在專案中以使用者角色分為 2 個埠, 使用者可以扮演多個角色, 但是線上上只能同時操作一個埠的業務, 這時每個埠都必須提供一個角色切換的功能, 以供使用者隨時在多個角色中切換, 這時在專案中就需要提供一個用於使用者自由切換角色的管理類作為 核心基礎業務 被這 2 個埠所依賴(類似 拉勾, Boss 直聘等 App 可以在招聘者和應聘者之間切換)
核心基礎業務 的劃分應該遵循是否為業務層大部分模組都需要的基礎業務, 以及一些需要在各個業務模組之間互動的業務, 都可以劃分為 核心基礎業務
2.2.3.2 公共服務
公共服務 是一個名為 CommonService 的 Module, 主要的作用是用於 業務層 各個模組之間的互動(自定義方法和類的呼叫), 包含自定義 Service 介面, 和可用於跨模組傳遞的自定義類
主要流程是:
提供服務的業務模組:
在公共服務(CommonService) 中宣告 Service 介面 (含有需要被呼叫的自定義方法), 然後在自己的模組中實現這個 Service 介面, 再通過 ARouter API 暴露實現類
使用服務的業務模組:
通過 ARouter 的 API 拿到這個 Service 介面(多型持有, 實際持有實現類), 即可呼叫 Service 介面中宣告的自定義方法, 這樣就可以達到模組之間的互動
跨模組傳遞的自定義類:
在 公共服務 中定義需要跨模組傳遞的自定義類後 (Service 中的自定義方法和 EventBus 中的事件實體類都可能需要用到自定義類), 就可以通過 ARouter API, 在各個模組的頁面之間跨模組傳遞這個自定義物件 (ARouter 要求在 URL 中使用 Json 引數傳遞自定義物件必須實現 SerializationService 介面)
Tips: 建議在 CommonService 中給每個需要提供服務的業務模組都建立一個單獨的包, 然後在這個包下放 Service 介面 和 需要跨模組傳遞的自定義類, 這樣更好管理
掌握公共服務層的用法最好要了解 ARouter 的 API
2.2.3.3 基礎 SDK
基礎 SDK 是一個名為 CommonSDK 的 Module, 其中包含了大量功能強大的 SDK, 提供給整個架構中的所有模組
MVPArms 是整個基礎層中最重要的模組, 可謂是整個元件化架構中的心臟, 裡面提供了開發一個完整專案所必須的一整套 API 和 SDK, 是整個專案的腳手架, 我用它來統一整個元件化方案的基礎設施, 使每一個模組更加健壯, 因為有了 MVPArms, 使得 ArmsComponent 成為了唯一提供完整基礎框架的元件化方案, 所以學習 ArmsComponent 之前必須先學會 MVPArms
學習 MVPArms 時請按以下排列順序依次學習:
基礎 SDK 中的 UI 元件 是一個名為 CommonRes 的 Module, 主要放置一些業務層可以通用的與 UI 有關的資源供所有業務層模組使用, 便於重用、管理和規範已有的資源
Tips: 值得注意的是, 業務層的某些模組如果出現有資源名命名相同的情況 (如兩個圖片命名相同), 當在宿主層整合所有模組時就會出現資源衝突的問題, 這時注意在每個模組的 build.gradle 中使用 resourcePrefix 標籤給每個模組下的資源名統一加上不同的字首即可解決此類問題
android {
defaultConfig {
minSdkVersion rootProject.ext.android["minSdkVersion"]
...
}
resourcePrefix "public_"
}
複製程式碼
可以放置的資源型別有:
- 通用的 Style, Theme
- 通用的 Layout
- 通用的 Color, Dimen, String
- 通用的 Shape, Selector, Interpolator
- 通用的 圖片資源
- 通用的 動畫資源
- 通用的 自定義 View
- 通用的第三方 自定義 View
其他 SDK 主要是 基礎 SDK 依賴的一些業務層可以通用的 第三方庫 和 第三方 SDK (比如 ARouter, 騰訊 X5 核心), 便於重用、管理和規範已有的 SDK 依賴
2.3 跨元件通訊
2.3.1 為什麼需要跨元件通訊?
因為各個業務模組之間是各自獨立的, 並不會存在相互依賴的關係, 所以一個業務模組是訪問不了其他業務模組的程式碼的, 如果想從 A 業務模組的 A 頁面跳轉到 B 業務模組的 B 頁面, 光靠模組自身是不能實現的, 所以這時必須依靠外界的其他媒介提供這個跨元件通訊的服務
2.3.2 跨元件通訊場景
跨元件通訊主要有以下兩種場景:
-
第一種是元件之間的頁面跳轉 (Activity 到 Activity, Fragment 到 Fragment, Activity 到 Fragment, Fragment 到 Activity) 以及跳轉時的資料傳遞 (基礎資料型別和可序列化的自定義類型別)
-
第二種是元件之間的自定義類和自定義方法的呼叫(元件向外提供服務)
2.3.3 跨元件通訊方案
其實以上兩種通訊場景甚至其他更高階的功能在 ARouter 中都已經被實現, ARouter 是 Alibaba 開源的一個 Android 路由中介軟體, 可以滿足很多元件化的需求, 也是作為本方案中比較重要的一環, 需要認真看下文件, 瞭解下基本使用
關於跨元件通訊框架, 本方案不做封裝, 專業的事交給專業的人做, 此類優秀框架為數眾多, 各有特點, 可以根據您的需求選擇您喜歡的框架, 不一定非得是 ARouter, 選擇 ARouter 也是因為 Alibaba 出品, 開源時間較長, 使用者眾多, 相對穩定, 出現問題比較好溝通
2.3.4 跨元件通訊方案分析
第一種元件之間的頁面跳轉不需要過多描述了, 算是 ARouter 中最基礎的功能, API 也比較簡單, 跳轉時想傳遞不同型別的資料也提供有相應的 API (如果想通過在 URL 中使用 Json 引數傳遞自定義物件, 需要實現 SerializationService, 詳情請查閱 ARouter 文件);
第二種元件之間的自定義類和自定義方法的呼叫要稍微複雜點, 需要 ARouter 配合架構中的 公共服務(CommonService) 實現, 主要流程在 公共服務(2.2.3.2) 中已有介紹, 這裡我畫了個示意圖, 以便大家更好理解
跨元件通訊示意圖
此種服務提供方式叫作 介面下沉, 看圖的同時請配合閱讀 公共服務(2.2.3.2) 中的主要流程便於理解
本方案中還提供有 EventBus 來作為服務提供的另一種方式, 大家知道 EventBus 因為其解耦的特性, 如果被濫用的話會使專案呼叫層次結構混亂, 不便於維護和除錯, 所以本方案使用 AndroidEventBus 其獨有的 Tag, 可以在開發時更容易定位傳送事件和接受事件的程式碼, 如果以元件名來作為 Tag 的字首進行分組, 也可以更好的統一管理和檢視每個元件的事件, 當然也不建議大家過多使用 EventBus
Tips: 每個跨元件通訊框架提供服務的方式都不同, 您也可以選擇其他框架的服務提供方式
2.3.5 跨元件傳遞複雜資料格式
在一般情況下基本資料型別就可以滿足大多數跨元件傳遞資料的需求, 但是在某些情況下也會需要傳遞複雜的自定義資料型別, 傳遞自定義型別在方案中也提供有兩種方式:
第一種在 公共服務(2.2.3.2) 中已提及, 就是在 公共服務 (CommonService) 中定義這個自定義類
第二種方式也比較簡單, 直接通過解析 Json 字串就可以傳遞
2.4 元件的生命週期
每個元件 (模組) 在測試階段都可以獨立執行, 在獨立執行時每個元件都可以指定自己的 Application, 這時元件自己管理生命週期就輕而易舉, 比如想在 onCreate 中初始化一些程式碼都可以輕鬆做到, 但是當進入整合除錯階段, 元件自己的 Application 已不可用, 每個元件都只能依賴於宿主的生命週期, 這時每個元件如果需要初始化自己獨有的程式碼, 該怎麼辦?
2.4.1 問題分析
在整合除錯階段, 宿主依賴所有元件, 但是每個元件卻不能依賴宿主, 意思是每個元件根本不知道自己的宿主是誰, 當然也就不能通過訪問程式碼的方式直接呼叫宿主的方法, 從而在宿主的生命週期里加入自己的邏輯程式碼
如果直接將每個模組的初始化程式碼直接複製進宿主的生命週期裡, 這樣未免過於暴力, 不僅程式碼耦合不易擴充套件, 而且程式碼還極易衝突, 所以修改宿主原始碼的方式也不可行
所以有沒有什麼方法可以讓每個元件在整合除錯階段都可以獨自管理自己的生命週期呢?
其實解決思路很簡單, 無非就是在開發時讓每個元件可以獨立管理自己的生命週期, 在執行時又可以讓每個元件的生命週期與宿主的生命週期進行合併 (在不修改或增加宿主程式碼的情況下完成)
2.4.2 可行方案分析
想在不更改宿主程式碼的情況下在宿主的生命週期中動態插入每個元件的程式碼, 這倒有點像 AOP 的意思
現有的解決方案大概有三種:
-
在基礎層中提供一個用於管理元件生命週期的管理類, 每個元件都手動將自己的生命週期實現類註冊進這個管理類, 在整合除錯時, 宿主在自己的 Application 對應生命週期方法中通過管理類去遍歷呼叫註冊的所有生命週期實現類即可
-
使用 AnnotationProcessor 解析註解在編譯期間生成原始碼自動註冊所有元件的生命週期實現類, 然後宿主再在對應的生命週期方法中去呼叫
-
使用 Javassist 在編譯時動態修改 class 檔案, 直接在宿主的對應生命週期方法中插入每個元件的生命週期邏輯
我最後還是選擇了第一種方法, 因為後面兩種方法雖然使用簡單, 還可以自動化的完成所有操作, 非常炫酷, 但是這兩種方法技術實現複雜, 在不同的 Gradle 版本中還會出現相容性問題影響整個專案的開發進度, 較難維護, 還會增加編譯時間
選擇第一種方法雖然增加了幾步操作, 但是簡單明瞭, 便與理解和維護, 後續人員加入也可以很快上手, 不受 Gradle 版本的影響, 也不會增加編譯時間
2.4.3 最終執行方案
第一種方案具體原理也沒什麼好說的, 比較簡單, 大概就是在基礎層中定義有生命週期方法 (attachBaseContext(), onCreate() ...) 的介面, 每個元件實現這個介面, 然後將實現類註冊進基礎層的管理器, 宿主通過管理器在對應的生命週期方法中呼叫所有的介面實現類, 典型的觀察者模式, 類似註冊點選事件
在 MVPArms 中這種方案的實現類叫作 ConfigModule, 每個元件都可以宣告一個或多個 ConfigModule 實現類, 內部實現較為複雜, 實現原理是 反射 + 代理 + 觀察者, 這個類也是整個 MVPArms 框架提供給開發者最重要的類
它可以給 MVPArms 框架配置大量的自定義引數, 包括專案中所有生命週期的管理 (Application, Activity, Fragment), 專案中所有網路請求的管理 (Retrofit, Okhttp, Glide),為框架提供了極大的擴充套件性, 使框架更加靈活
3 專案講解
專案地址 : ArmsComponent
3.1 如何讓元件獨立執行?
在專案根目錄的 gradle.properties 中, 改變 isBuildModule 的值即可
#isBuildModule 為 true 時可以使每個元件獨立執行, false 則可以將所有元件整合到宿主 App 中
isBuildModule=true
複製程式碼
3.2 配置 AndroidManifest
由於元件在獨立執行時和整合到宿主時可能需要 AndroidManifest 配置不一樣的引數, 比如元件在獨立執行時需要其中的一個 Activity 配置了 <action android:name="android.intent.action.MAIN"/>
作為入口, 而當元件整合到宿主中時, 則依賴於宿主的入口, 所以不需要配置 <action android:name="android.intent.action.MAIN"/>
, 這時我們就需要兩個不同的 AndroidManifest 應對不同的情況
在元件的 build.gradle 中加入以下程式碼, 即可指定不同的 AndroidManifest, 具體請看專案程式碼
android {
sourceSets {
main {
jniLibs.srcDirs = ['libs']
if (isBuildModule.toBoolean()) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
}
}
}
}
複製程式碼
3.3 配置 ConfigModule(GlobalConfiguration)
ConfigModule 在 最終執行方案(2.4.3) 中提到過, GlobalConfiguration 是實現類, 他可以給框架配置大量的自定義引數
專案 CommonSDK 中提供有一個 GlobalConfiguration 用於配置每個元件都會用到的公用配置資訊, 但是每個元件可能都需要有一些私有配置, 比如初始化一些特有屬性, 所以在每個元件中也需要實現 ConfigModule, 具體請看專案程式碼
需要注意的是, 在 配置 AndroidManifest(3.2) 中提到過元件在獨立執行時和整合到宿主時所需要的配置是不一樣的, 當元件在獨立執行時需要在 AndroidManifest 中宣告自己私有的 GlobalConfiguration 和 CommonSDK 公有的 GlobalConfiguration, 但在整合到宿主時, 由於宿主已經宣告瞭 CommonSDK 的公有 GlobalConfiguration, 所以在 AndroidManifest 只需要宣告自己私有的 GlobalConfiguration, 這裡也說明了 AndroidManifest 在不同的情況需要做出不同的配置
3.4 RouterHub
RouterHub 用來定義路由器的路由地址, 以元件名作為字首, 對每個元件的路由地址進行分組, 可以統一檢視和管理所有分組的路由地址
RouterHub 存在於基礎庫, 可以被看作是所有元件都需要遵守的通訊協議, 裡面不僅可以放路由地址常量, 還可以放跨元件傳遞資料時命名的各種 Key 值, 再配以適當註釋, 任何元件開發人員不需要事先溝通只要依賴了這個協議, 就知道了各自該怎樣協同工作, 既提高了效率又降低了出錯風險, 約定的東西自然要比口頭上說強
Tips: 如果您覺得把每個路由地址都寫在基礎庫的 RouterHub 中, 太麻煩了, 也可以在每個元件內部建立一個私有 RouterHub, 將不需要跨元件的路由地址放入私有 RouterHub 中管理, 只將需要跨元件的路由地址放入基礎庫的公有 RouterHub 中管理, 如果您不需要集中管理所有路由地址的話, 這也是比較推薦的一種方式
路由地址的命名規則為 元件名 + 頁面名, 如訂單元件的訂單詳情頁的路由地址可以命名為 "/order/OrderDetailActivity"
ARouter 將路由地址中第一個 '/' 後面的字元叫作 Group, 比如上面的示例路由地址中 order 就是 Group, 以 order 開頭的地址都被分配該 Group 下
Tips: 切記不同的元件中不能出現名稱一樣的 Group, 否則會發生該 Group 下的部分路由地址找不到的情況!!!
所以每個元件使用自己的元件名作為 Group 是比較好的選擇, 畢竟元件不會重名
3.5 EventBusHub
AndroidEventBus 作為本方案提供的另一種跨元件通訊方式 (第一種跨元件通訊方式是 公共服務(2.2.3.2)), AndroidEventBus 比 greenrobot 的 EventBus 多了一個 Tag, 在元件化中更容定位和管理事件
EventBusHub 用來定義 AndroidEventBus 的 Tag 字串, 以元件名作為 Tag 字首, 對每個元件的事件進行分組
Tag 的命名規則為 元件名 + 頁面名 + 動作, 比如需要使用 AndroidEventBus 通知訂單元件的訂單詳情頁進行重新整理, 可以將這個重新整理方法的 Tag 命名為 "order/OrderDetailActivity/refresh"
Tips: 基礎庫中的 EventBusHub 僅用來存放需要跨元件通訊的事件的 Tag, 如果某個事件只想在元件內使用 AndroidEventBus 進行通訊, 那就讓元件自行管理這個事件的 Tag
3.6 在專案中使用多個不同的域名
在專案中, 有 知乎 、乾貨集中營、稀土掘金 三個模組, 這三個模組網路介面的域名都不一樣, 但是在專案中卻可以統一使用框架提供的同一個 Retrofit 進行網路請求, 這是怎麼做到的呢? 這是採用本人的另一個庫 RetrofitUrlManager, 它可以使 Retrofit 同時支援多個 BaseUrl 以及動態改變 BaseUrl
公眾號
掃碼關注我的公眾號 JessYan,一起學習進步,如果框架有更新,我也會在公眾號上第一時間通知大家
Hello 我叫 JessYan,如果您喜歡我的文章,可以在以下平臺關注我
- 個人主頁: jessyan.me
- GitHub: github.com/JessYanCodi…
- 掘金: juejin.cn/user/976022…
- 簡書: www.jianshu.com/u/1d0c0bc63…
- 微博: weibo.com/u/178626251…
-- The end