優秀框架原始碼分析系列(一)讓解耦更輕鬆!多程序元件化框架-ModularizationArchitecture
今天開始,我將陸續推出一系列的Android相關的優秀開源專案原始碼分析系列文章,每一期選取一個框架來進行分析解構。幫助大家更好的瞭解優秀框架的設計思想。分析的方式會選擇從原始碼本身進行討論,學習其設計思想,取長補短,每一個設計都有它值得學習的地方,大家各取所需,我相信,無論是成功的經驗,還是失敗的教訓,都是一樣有價值的。
ModularizationArchitecture概述
ModularizationArchitecture是一套Android徹底元件化框架。它主要提供了以下幾個功能:
- 程序間,程序內元件間的路由通訊機制
- 程序間,程序內元件行為功能的封裝機制
- 元件的載入(初始化)、解除安裝機制
- 提供元件化核心基類
工程結構
macore maindemo musicdemo picdemo webdemo
元件的框架
每個獨立程序的元件,均需包含如下幾個部分:
Logic Provider Action RouterConnectService
如果是非獨立程序的元件,則只需包含如下幾個部分:
Logic Provider Action
元件化核心之macore
macore
提供了框架基礎,為元件化提供基礎功能。
元件間通訊機制
元件間通訊採用了C/S架構,跨程序通訊採用了Binder呼叫。其核心是通過 LocalRouter
和 WideRouter
兩個類來實現。
路由器( LocalRouter
、 WideRouter
)
本地元件間通訊通過 LocalRouter
來完成,程序間元件通訊是通過WideRouter來完成。如果是跨程序模式, WideRouter
則獨自執行在一個路由程序中。檢視 macore
中的 MaApplication.java
中的 startWideRouter()
方法和 AndroidManifest.xml
不難發現, macore
執行後會建立一個 com.spiny.ma.widerouter
的程序。
這裡分別給出 LocalRouter
和 WideRouter中route
方法的邏輯圖,以便更好的理解。
LocalRouter.route()

WideRouter.route()

路由器守護服務(LocalRouterConnectService、WideRouterConnectService)
路由器守護服務用來實現 LocalRouter
和 WideRouter
的雙向互聯。
LocalRouter
作為元件的路由,既負責向WideRouter傳送元件內部的跨程序呼叫,又負責接收來自 WideRouter
的跨程序呼叫。當其負責接收外部呼叫時,是作為C/S架構中的 Service
存在的,所以這個服務通過 LocalRouterConnectService
來提供。 WideRouter
通過 LocalRouterConnectService
向該元件傳送請求,它是元件向外界提供能力的橋樑。
正如剛才說到的, WideRouter
本身提供的對外功能就是為各個元件中轉請求,實際上,它提供的就是一種路由服務,從這個層面上來講,它也是一個元件。所以它也需要一個 Service
向外提供服務,即 WideRouterConnectService
,其它的 LocalRouter
通過連線到這個服務,與 WideRouter
建立通訊通道。
在多應用多產品開發場景日益普遍的今天,在多個應用內同時引入ma框架,由多個WideRouter組成更大的元件化網路,也不失為一種策略。尤其是當我們要對產品進行平臺化演進時,將眾多的基礎功能服務以一個App的形式提供出去,暴露多種服務供其他應用呼叫的時候,元件化思想會為多模組,多應用並行開發提供可能。
元件生命週期
元件生命週期管理器(BaseApplicationLogic)
設計了一個包含類似 Application
一樣的生命週期管理類,每一個元件都實現一個這樣的生命週期管理類,負責處理元件本身的初始化和去初始化動作。使用元件時,將這個生命週期類與應用的 Application
類進行繫結,這樣元件的生命週期就和應用的生命週期綁定了。
元件其他輔助類
Wrapper
-
PriorityLogicWrapper
:在多元件的生命週期管理上,元件的載入可能需要維護一定的順序以保證邏輯的正確性。PriorityLogicWrapper對管理器進行了包裝,增加了一個優先順序屬性,這樣,程式員只需要在最開始指定好優先順序,就不用擔心在後續的維護過程中因過失而使初始化失序。 -
ConnectServiceWrapper
:承載繼承自LocalRouterConnectService的類。所有元件中實現的LocalRouterConnectService擴充套件類,都將在macore元件中被ConnectServiceWrapper包裝起來。可能就是為了寫起來方便吧。
Action、Provider
- MaAction :所有Action的基類。元件可以通過繼承它實現自己對外提供的服務。
- MaProvider :所有Provider的基類。
- MaActionResult :服務呼叫在元件間傳遞的返回的結果類。
- ErrorAction :當請求的服務不存在或不可用時,預設返回的錯誤。
RouterRequest、RouterResponse
- RouterRequest :由呼叫方建立的,服務呼叫的請求封裝類。其內部實現了類似訊息池一樣的陣列。以保證物件建立更高效。
- RouterResponse :對呼叫結果的包裝類,承載了呼叫的返回情況。其中包含了字串化的MaActionResult。
MaApplication
擴充套件自 Application
的類,將元件化框架的基礎元件初始化框架封裝在其中。這樣,框架的使用者無需關心框架的初始化細節,而只需要關注元件本身的生命週期即可。
主程式(Host)實現
Host
是整個應用的 Application
實現部分,其他元件都是以 Library
的方式存在的。 Host
負責對其他元件進行註冊,並將應用的生命週期和 macore
進行繫結。這些都在 MyApplication
中實現。
@Override public void initializeAllProcessRouter() { WideRouter.registerLocalRouter("com.spinytech.maindemo",MainRouterConnectService.class); WideRouter.registerLocalRouter("com.spinytech.maindemo:music",MusicRouterConnectService.class); WideRouter.registerLocalRouter("com.spinytech.maindemo:pic",PicRouterConnectService.class); } @Override protected void initializeLogic() { registerApplicationLogic("com.spinytech.maindemo",999, MainApplicationLogic.class); registerApplicationLogic("com.spinytech.maindemo",998, WebApplicationLogic.class); registerApplicationLogic("com.spinytech.maindemo:music",999, MusicApplicationLogic.class); registerApplicationLogic("com.spinytech.maindemo:pic",999, PicApplicationLogic.class); } @Override public boolean needMultipleProcess() { return true; } 複製程式碼
Host
同時也是一個元件,其對外也同樣提供服務。所以,它也對應實現了 Logic
, Provider
以及一系列 Action
。由於開啟了多程序模式,所以也實現了 RouterConnectService
,它擴充套件自 LocalRouterConnectService
。
其他元件
工程下還包含了其他幾個示例元件:musicdemo、picdemo、webdemo。
其中musicdemo和picdemo均為單獨執行在一個程序中的元件,而webdemo與maindemo執行在一個程序中。當我們需要新開發某個元件的時候,只需要按元件的實際功能實現 Action
、 Provider
以及 Logic
即可。如果是跨程序元件,還需要擴充套件實現 LocalRouterConnectService
。
總結
元件化提出已經很久了,它可以從很多方面解決我們實際專案開發中的問題,無論是技術上的實現問題,還是人員組織結構和專案分工上,都提供了很好的方式。換句話說,因為在架構上解決了耦合問題,使得專案開發的組織上也可以很輕鬆的實現解耦,不失為一舉兩得。在此,我們再重複一下元件化框架解決的幾大問題:
- 程式碼解耦
- 程式碼隔離(可見性)
- 元件(功能模組)單獨除錯
- 整合除錯
- 元件(功能模組)生命週期管理
- 元件間資料通訊
原始碼地址
下面是專案的原始碼地址:
ofollow,noindex">ModularizationArchitecture原始碼
我讀了一遍後,做了些簡單的Bug修復,下面這個是我fork後的地址:
修改後的ModularizationArchitecture