MVPArms官方快速組件化方案開源,來自5K star的信賴

原文地址: https://www.jianshu.com/p/f671dd76868fjava

Logo

0 前言

MVPArms 從兩年前開源至今, 已經累積了 5k star, 得到了上千個商業項目的信賴和承認網絡

回顧兩年前, 那時 MVPArms 還沒誕生, MVPDagger2RxjavaRetrofit 這些技術在國內纔剛剛開始流行, 在網上能搜索到的中文學習資料遠沒有如今這麼豐富, 特別是 Dagger, 在網上能搜索到的文章甚至有不少講的是 SquareDagger1, 學習資料的匱乏加上 Dagger2 自己就是塊硬骨頭, 讓本人在學習的道路上不知道多走了多少彎路架構

從那時開始, 讓初學者都可以快速搭建一個 MVP + Dagger2 + Retrofit + Rxjava 項目的種子就已經深埋在心中, 後面通過不懈的努力, MVPArms 終於誕生並開源了, 開源之後只是一直堅持將 代碼, 註釋文檔 作到極致, 沒想到的是, MVPArms 能發展到現在的體量, 感謝開源!框架

0.1 起源

這是 MVPArms 的起源, ArmsComponent 的起源一樣類似, 從去年開始, 組件化逐漸火熱起來, 本人也在去年年初開始在公司項目中進行組件化, 一切還算順利ide

那時一樣的種子繼續埋在了心中, 我想讓剛剛接觸組件化的初學者也能快速搭建一箇中小型的組件化項目, 通過一年的不斷優化, 終於決定將其開源(MVPArms 官方組件化方案 ArmsComponent)組件化

Github : 您的 Star 是我堅持的動力 ✊

0.2 組件化方案分析

看了不少組件化方案, 因此總結了在組件化中很重要的三個大點:

  1. 基礎庫(網絡請求、圖片加載等)的封裝
  2. 路由框架(頁面跳轉, 服務提供)
  3. 業務組件的劃分和代碼隔離

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, 以爲接入成本太大, 不要緊, 借鑑下 MVPArmsArmsComponent 的代碼, 嘗試改造本身的項目, 也是個不錯的選擇

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 組件化架構圖

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 公共服務

公共服務 是一個名爲 CommonServiceModule, 主要的做用是用於 業務層 各個模塊之間的交互(自定義方法和類的調用), 包含自定義 Service 接口, 和可用於跨模塊傳遞的自定義類

主要流程是:

提供服務的業務模塊:

在公共服務(CommonService) 中聲明 Service 接口 (含有須要被調用的自定義方法), 而後在本身的模塊中實現這個 Service 接口, 再經過 ARouter API 暴露實現類

使用服務的業務模塊:

經過 ARouterAPI 拿到這個 Service 接口(多態持有, 實際持有實現類), 便可調用 Service 接口中聲明的自定義方法, 這樣就能夠達到模塊之間的交互

跨模塊傳遞的自定義類:

公共服務 中定義須要跨模塊傳遞的自定義類後 (Service 中的自定義方法和 EventBus 中的事件實體類均可能須要用到自定義類), 就能夠經過 ARouter API, 在各個模塊的頁面之間跨模塊傳遞這個自定義對象 (ARouter 要求在 URL 中使用 Json 參數傳遞自定義對象必須實現 SerializationService 接口)

Tips: 建議在 CommonService 中給每一個須要提供服務的業務模塊都創建一個單獨的包, 而後在這個包下放 Service 接口 和 須要跨模塊傳遞的自定義類, 這樣更好管理

掌握公共服務層的用法最好要了解 ARouter 的 API

點擊查閱 ARouter 文檔

2.2.3.3 基礎 SDK

基礎 SDK 是一個名爲 CommonSDKModule, 其中包含了大量功能強大的 SDK, 提供給整個架構中的全部模塊

2.2.3.3.1 MVPArms

MVPArms 是整個基礎層中最重要的模塊, 可謂是整個組件化架構中的心臟, 裏面提供了開發一個完整項目所必須的一整套 APISDK, 是整個項目的腳手架, 我用它來統一整個組件化方案的基礎設施, 使每個模塊更加健壯, 由於有了 MVPArms, 使得 ArmsComponent 成爲了惟一提供完整基礎框架的組件化方案, 因此學習 ArmsComponent 以前必須先學會 MVPArms

學習 MVPArms 時請按如下排列順序依次學習:

1.點擊學習 Demo

2.點擊查閱 詳細文檔

3.點擊下載 一鍵生成代碼插件

2.2.3.3.2 UI 組件

基礎 SDK 中的 UI 組件 是一個名爲 CommonResModule, 主要放置一些業務層能夠通用的與 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

2.2.3.3.3 其餘 SDK

其餘 SDK 主要是 基礎 SDK 依賴的一些業務層能夠通用的 第三方庫第三方 SDK (好比 ARouter, 騰訊 X5 內核), 便於重用、管理和規範已有的 SDK 依賴

2.3 跨組件通訊

2.3.1 爲何須要跨組件通訊?

由於各個業務模塊之間是各自獨立的, 並不會存在相互依賴的關係, 因此一個業務模塊是訪問不了其餘業務模塊的代碼的, 若是想從 A 業務模塊的 A 頁面跳轉到 B 業務模塊的 B 頁面, 光靠模塊自身是不能實現的, 因此這時必須依靠外界的其餘媒介提供這個跨組件通訊的服務

2.3.2 跨組件通訊場景

跨組件通訊主要有如下兩種場景:

  • 第一種是組件之間的頁面跳轉 (ActivityActivity, FragmentFragment, ActivityFragment, FragmentActivity) 以及跳轉時的數據傳遞 (基礎數據類型和可序列化的自定義類類型)

  • 第二種是組件之間的自定義類和自定義方法的調用(組件向外提供服務)

2.3.3 跨組件通訊方案

其實以上兩種通訊場景甚至其餘更高階的功能在 ARouter 中都已經被實現, ARouterAlibaba 開源的一個 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 的意思

現有的解決方案大概有三種:

  1. 在基礎層中提供一個用於管理組件生命週期的管理類, 每一個組件都手動將本身的生命週期實現類註冊進這個管理類, 在集成調試時, 宿主在本身的 Application 對應生命週期方法中經過管理類去遍歷調用註冊的全部生命週期實現類便可

  2. 使用 AnnotationProcessor 解析註解在編譯期間生成源代碼自動註冊全部組件的生命週期實現類, 而後宿主再在對應的生命週期方法中去調用

  3. 使用 Javassist 在編譯時動態修改 class 文件, 直接在宿主的對應生命週期方法中插入每一個組件的生命週期邏輯

我最後仍是選擇了第一種方法, 由於後面兩種方法雖然使用簡單, 還能夠自動化的完成全部操做, 很是炫酷, 可是這兩種方法技術實現複雜, 在不一樣的 Gradle 版本中還會出現兼容性問題影響整個項目的開發進度, 較難維護, 還會增長編譯時間

選擇第一種方法雖然增長了幾步操做, 可是簡單明瞭, 便與理解和維護, 後續人員加入也能夠很快上手, 不受 Gradle 版本的影響, 也不會增長編譯時間

2.4.3 最終執行方案

第一種方案具體原理也沒什麼好說的, 比較簡單, 大概就是在基礎層中定義有生命週期方法 (attachBaseContext(), onCreate() ...) 的接口, 每一個組件實現這個接口, 而後將實現類註冊進基礎層的管理器, 宿主經過管理器在對應的生命週期方法中調用全部的接口實現類, 典型的觀察者模式, 相似註冊點擊事件

MVPArms 中這種方案的實現類叫做 ConfigModule, 每一個組件均可以聲明一個或多個 ConfigModule 實現類, 內部實現較爲複雜, 實現原理是 反射 + 代理 + 觀察者, 這個類也是整個 MVPArms 框架提供給開發者最重要的類

它能夠給 MVPArms 框架配置大量的自定義參數, 包括項目中全部生命週期的管理 (Application, Activity, Fragment), 項目中全部網絡請求的管理 (Retrofit, Okhttp, Glide),爲框架提供了極大的擴展性, 使框架更加靈活

3 項目講解

ArmsComponent

項目地址 : 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 中聲明本身私有的 GlobalConfigurationCommonSDK 公有的 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)), AndroidEventBusgreenrobotEventBus 多了一個 Tag, 在組件化中更容定位和管理事件

EventBusHub 用來定義 AndroidEventBusTag 字符串, 以組件名做爲 Tag 前綴, 對每一個組件的事件進行分組

Tag 的命名規則爲 組件名 + 頁面名 + 動做, 好比須要使用 AndroidEventBus 通知訂單組件的訂單詳情頁進行刷新, 能夠將這個刷新方法的 Tag 命名爲 "order/OrderDetailActivity/refresh"

Tips: 基礎庫中的 EventBusHub 僅用來存放須要跨組件通訊的事件的 Tag, 若是某個事件只想在組件內使用 AndroidEventBus 進行通訊, 那就讓組件自行管理這個事件的 Tag

3.6 在項目中使用多個不一樣的域名

在項目中, 有 知乎乾貨集中營稀土掘金 三個模塊, 這三個模塊網絡接口的域名都不同, 可是在項目中卻能夠統一使用框架提供的同一個 Retrofit 進行網絡請求, 這是怎麼作到的呢? 這是採用本人的另外一個庫 RetrofitUrlManager, 它可使 Retrofit 同時支持多個 BaseUrl 以及動態改變 BaseUrl

公衆號

掃碼關注個人公衆號 JessYan,一塊兒學習進步,若是框架有更新,我也會在公衆號上第一時間通知你們


Hello 我叫 JessYan,若是您喜歡個人文章,能夠在如下平臺關注我

-- The end

相關文章
相關標籤/搜索