寫在前面
今天開始,我將陸續推出一系列的Android相關的優秀開源專案原始碼分析系列文章,每一期選取一個框架來進行分析解構。幫助大家更好的瞭解優秀框架的設計思想。分析的方式會選擇從原始碼本身進行討論,學習其設計思想,取長補短,每一個設計都有它值得學習的地方,大家各取所需,我相信,無論是成功的經驗,還是失敗的教訓,都是一樣有價值的。
ModularizationArchitecture概述
ModularizationArchitecture是一套Android徹底元件化框架。它主要提供了以下幾個功能:
- 程式間,程式內元件間的路由通訊機制
- 程式間,程式內元件行為功能的封裝機制
- 元件的載入(初始化)、解除安裝機制
- 提供元件化核心基類
工程結構
macore
:元件化核心庫maindemo
:主程式(Host)musicdemo
:播放器元件picdemo
:圖片元件webdemo
:網頁元件
元件的框架
每個獨立程式的元件,均需包含如下幾個部分:
Logic
:元件的生命週期抽象模板,相當於元件的Application類Provider
:一組元件行為的抽象,其內部包含一組Action。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
。
總結
元件化提出已經很久了,它可以從很多方面解決我們實際專案開發中的問題,無論是技術上的實現問題,還是人員組織結構和專案分工上,都提供了很好的方式。換句話說,因為在架構上解決了耦合問題,使得專案開發的組織上也可以很輕鬆的實現解耦,不失為一舉兩得。在此,我們再重複一下元件化框架解決的幾大問題:
- 程式碼解耦
- 程式碼隔離(可見性)
- 元件(功能模組)單獨除錯
- 整合除錯
- 元件(功能模組)生命週期管理
- 元件間資料通訊
原始碼地址
下面是專案的原始碼地址:
我讀了一遍後,做了些簡單的Bug修復,下面這個是我fork後的地址:
修改後的ModularizationArchitecture
最後,感謝Spiny Wang的優秀開源框架
題目徵集
大家有想了解的優秀框架,也可以私信我。我會篩選關注度高的框架進行解讀。感謝大家的關注和支援!
小銘出品,必屬精品
歡迎關注xNPE技術論壇,更多原創乾貨每日推送。