優秀框架原始碼分析系列(一)讓解耦更輕鬆!多程式元件化框架-ModularizationArchitecture

xNPE發表於2018-09-30

寫在前面

今天開始,我將陸續推出一系列的Android相關的優秀開源專案原始碼分析系列文章,每一期選取一個框架來進行分析解構。幫助大家更好的瞭解優秀框架的設計思想。分析的方式會選擇從原始碼本身進行討論,學習其設計思想,取長補短,每一個設計都有它值得學習的地方,大家各取所需,我相信,無論是成功的經驗,還是失敗的教訓,都是一樣有價值的。

ModularizationArchitecture概述

ModularizationArchitecture是一套Android徹底元件化框架。它主要提供了以下幾個功能:

  • 程式間,程式內元件間的路由通訊機制
  • 程式間,程式內元件行為功能的封裝機制
  • 元件的載入(初始化)、解除安裝機制
  • 提供元件化核心基類

工程結構

  • macore:元件化核心庫
  • maindemo:主程式(Host)
  • musicdemo:播放器元件
  • picdemo:圖片元件
  • webdemo:網頁元件

元件的框架

每個獨立程式的元件,均需包含如下幾個部分:

  • Logic:元件的生命週期抽象模板,相當於元件的Application類
  • Provider:一組元件行為的抽象,其內部包含一組Action。
  • Action:元件行為,即對外提供的服務項(或稱為最小粒度的功能點)
  • RouterConnectService:多程式時,元件的守護服務

如果是非獨立程式的元件,則只需包含如下幾個部分:

  • Logic:同上
  • Provider:同上
  • Action:同上

元件化核心之macore

macore提供了框架基礎,為元件化提供基礎功能。

元件間通訊機制

元件間通訊採用了C/S架構,跨程式通訊採用了Binder呼叫。其核心是通過LocalRouterWideRouter兩個類來實現。

路由器(LocalRouterWideRouter

本地元件間通訊通過LocalRouter來完成,程式間元件通訊是通過WideRouter來完成。如果是跨程式模式,WideRouter則獨自執行在一個路由程式中。檢視macore中的MaApplication.java中的startWideRouter()方法和AndroidManifest.xml不難發現,macore執行後會建立一個com.spiny.ma.widerouter的程式。

這裡分別給出LocalRouterWideRouter中route方法的邏輯圖,以便更好的理解。

LocalRouter.route()

優秀框架原始碼分析系列(一)讓解耦更輕鬆!多程式元件化框架-ModularizationArchitecture

WideRouter.route()

優秀框架原始碼分析系列(一)讓解耦更輕鬆!多程式元件化框架-ModularizationArchitecture

路由器守護服務(LocalRouterConnectService、WideRouterConnectService)

路由器守護服務用來實現LocalRouterWideRouter的雙向互聯。

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執行在一個程式中。當我們需要新開發某個元件的時候,只需要按元件的實際功能實現ActionProvider以及Logic即可。如果是跨程式元件,還需要擴充套件實現LocalRouterConnectService

總結

元件化提出已經很久了,它可以從很多方面解決我們實際專案開發中的問題,無論是技術上的實現問題,還是人員組織結構和專案分工上,都提供了很好的方式。換句話說,因為在架構上解決了耦合問題,使得專案開發的組織上也可以很輕鬆的實現解耦,不失為一舉兩得。在此,我們再重複一下元件化框架解決的幾大問題:

  • 程式碼解耦
  • 程式碼隔離(可見性)
  • 元件(功能模組)單獨除錯
  • 整合除錯
  • 元件(功能模組)生命週期管理
  • 元件間資料通訊

原始碼地址

下面是專案的原始碼地址:

ModularizationArchitecture原始碼

我讀了一遍後,做了些簡單的Bug修復,下面這個是我fork後的地址:

修改後的ModularizationArchitecture

最後,感謝Spiny Wang的優秀開源框架

題目徵集

大家有想了解的優秀框架,也可以私信我。我會篩選關注度高的框架進行解讀。感謝大家的關注和支援!

小銘出品,必屬精品

歡迎關注xNPE技術論壇,更多原創乾貨每日推送。

優秀框架原始碼分析系列(一)讓解耦更輕鬆!多程式元件化框架-ModularizationArchitecture

相關文章