1. 程式人生 > >Android 架構分層中的模組、元件、外掛,元件間通訊(路由等)

Android 架構分層中的模組、元件、外掛,元件間通訊(路由等)

模組化、元件化、外掛化。

計算機界有一句名言:“電腦科學領域的任何問題都可以通過增加一箇中間層來解決。
-- 頁面元件化的設計思路是:
 1.將頁面拆分為粒度更小的元件,元件內部除了包含UI實現,還包含資料層和邏輯層;
 2.元件提供個性化配置滿足兩端差異需求,如果無法滿足再通過代理拋到上層處理。
頁面元件化是一個良好的設計,但它主要適用於解決Activity巨大化的問題。由於底層差異巨大的情況,使得頁面元件化很難實現大規模的複用,複用效率低。另一方面,頁面元件化也沒有為2端差異性預留可伸縮的空間。

 1.Android 外掛化 —— 指將一個程式劃分為不同的部分,比如一般 App 的面板樣式就可以看成一個外掛;
 2.Android 元件化 —— 這個概念實際跟上面相差不那麼明顯,元件和外掛較大的區別就是:元件是指通用及複用性較高的構件,比如圖片快取就可以看成一個元件被多個 App 共用;
 3.Android動態載入 — 這個實際是更高層次的概念,也有叫法是熱載入或 Android 動態部署,指容器(App)在運⾏狀態下動態載入某個模組,從而新增功能或改變某⼀部分行為. 

  元件化實際上是一種程式設計思想,而外掛化是一種實實在在的技術,元件化是為了程式碼的高度複用而出現的,我們可以通過把不同模組的業務做成一個個獨立的 Library ,可以單獨對這些 Library 進行版本管理,從而可以供給給想使用它的一切 Apk,這樣做的好處不僅可以提高程式碼的複用性,而且也可以幫助專案進行業務解耦,提升開發效率。
  外掛化是為了解決應用越來越龐大、佔用記憶體越來越高、Apk 體量過大、解決65535方法數等複雜問題而出現的,外掛化會把各個解耦業務單獨的封裝到 APK 外掛中,通過外掛附屬到宿主 APK 中,從而完成功能的實現,這些獨立的 APK 外掛甚至可以單獨打包成應用。比如手機淘寶,它不僅有淘寶這個宿主應用本身的一些功能,還有一些像聚划算、書城這類的其他應用也需要接入進來,那麼如果沒有外掛化,像聚划算的開發人員就要同時維護兩套程式碼,一套是自己的聚划算專案,一套是接入到手淘的聚划算專案,出現了Bug也得同時去兩套程式碼去更改,這在管理和開發效率上就會非常受限。但如果我們把聚划算做成一個外掛,那麼哪個應用要接入聚划算,只要把這個 APK 包接入進來即可,在程式碼中的就是一些 compile 和 gradle 的配置,外掛內部的程式碼完全不用你操心了。

阿里頁面路由ARouter- https://github.com/XinRan5312/QXFirstARouter
AbstractProcessor Test Demo- https://github.com/zyao89/DemoAbstractProcessor
阿里ARouter使用及原始碼解析- https://www.jianshu.com/p/46d174f37e82
  通過註解處理器RouteProcessor生成的,關於如何自定義註解處理器,可以閱讀Android編譯時註解APT實戰(AbstractProcessor)https://www.jianshu.com/p/07ef8ba80562,同時也需要學習JavaPoet的基本使用。
  那些在執行時(Runtime)通過反射機制執行處理的註解,而是討論在編譯時(Compile time)處理的註解。
  ARouter 的初始化只做了一件事,找到自己編譯期產生的清單檔案,把 Group 、Interceptor 、Provider 三種清單載入到
Warehouse 記憶體倉庫中。

-- WMRouter:美團外賣Android開源路由框架,WMRouter主要提供URI分發、ServiceLoader兩大功能。
WMRouter是一款Android路由框架,基於元件化的設計思路,最初用於解決美團外賣C端App在業務演進過程中的實際問題
WMRouter- https://github.com/meituan/WMRouter
 WMRouter路由框架,借鑑網路請求的思想,設計了基於UriRequest、UriHandler、UriInterceptor的URI分發機制,在保證功能靈活強大的同時,又儘可能的降低了使用難度;另一方面,借鑑SPI的設計思想、Java和美團平臺的ServiceLoader實現,開發了自己的ServiceLoader模組,解決外賣平臺化過程中的四個問題(通訊問題、複用問題、依賴注入、編譯問題)。
  原有的單個工程拆分成多個工程,就不可避免的涉及到多工程之間的耦合問題,主要包括通訊問題、複用問題、依賴注入、編譯問題.
WMRouter:美團外賣Android開源路由框架- https://blog.csdn.net/MeituanTech/article/details/82108690

  架構裡面提供了二種平級間的通訊方式:scheme路由和美團自建的ServiceLoaders sdk。scheme路由本質上是利用Android的scheme原理進行通訊,ServiceLoader本質上是利用的Java反射機制進行通訊。

> 外掛化
- 我的Android重構之旅:外掛化篇- https://blog.csdn.net/c6E5UlI1N/article/details/81125532

  外掛化踩坑之路——Small和Atlas方案,阿里另一款熱修復方案 Andfix。
  Small 是一款輕量級的跨平臺外掛化框架,更側重於業務的解耦,元件化開發。所有的外掛支援內置於宿主包中,並且高度透明,外掛編碼、佈局編寫方式、除錯與獨立整包開發無異,通過 URL 來進行宿主與外掛之間的通訊和傳遞引數。

> 專案元件化
  那麼什麼是元件化?概括為:元件化是基於可重用目的將專案按照具體業務需求進行拆分,並能將拆分得到的元件進行靈活重組,減小耦合(業務需求上的拆分)。
 元件化:隨著業務量的不斷增長,app也會不斷的膨脹,開發團隊的規模和工作量也會逐漸增大,面對所衍生的64K問題、協作開發問題等,app一般都會走向元件化。元件化就是將APP按照一定的功能和業務拆分成多個元件module,不同的元件獨立開發,元件化不僅能夠提供團隊的工作效率,還能夠提高應用效能。而元件化的前提就是解耦,那麼我們首先要做的就是解耦頁面之間的依賴關係。
 Native與H5的問題:現在的APP很少是純Native的,也很少會有純H5的,一般情況下都是將兩者進行結合。這時候就需要非常便捷並且統一的跳轉方案,因為在H5中是無法使用StartActivity()跳轉到Native頁面的,而從Native跳轉到H5頁面也只能通過配置瀏覽器的方式實現。

簡單聊聊Android Architecture Componets(元件設計)- https://github.com/googlesamples/android-architecture-components
元件化專案- https://github.com/JessYanCoding/ArmsComponent
Android元件化方案- http://blog.csdn.net/guiying712/article/details/55213884
Android 元件化探索與思考- https://github.com/WuXiaolong/ModularSample
Android專案元件化AndroidModulePattern(阿里ARouter作為路由)- https://github.com/guiying712/AndroidModulePattern
Router activities and methods with url for android- https://github.com/mzule/ActivityRouter
Android元件化方案- http://blog.csdn.net/guiying712/article/details/55213884
Android元件化之終極方案- http://blog.csdn.net/guiying712/article/details/78057120
Android元件化和外掛化開發- https://www.cnblogs.com/android-blogs/p/5703355.html

-- 模組化是一種指導理念,其核心思想就是分而治之、降低耦合。元件化的目標之一就是降低整體(app)與器官(元件)的依賴關係,缺少任何一個器官app都是可以存在並正常執行的。
  元件化和外掛化的最大區別(應該也是唯一區別)就是元件化在執行時不具備動態新增和修改元件的功能,但是外掛化是可以的。 
-- 要實現元件化,不論採用什麼樣的技術路徑,需要考慮的問題主要包括下面幾個: 
 * 程式碼解耦。如何將一個龐大的工程拆分成有機的整體? 
 * 元件單獨執行。上面也講到了,每個元件都是一個完整的整體,如何讓其單獨執行和除錯呢? 
 * 資料傳遞。因為每個元件都會給其他元件提供的服務,那麼主專案(Host)與元件、元件與元件之間如何傳遞資料? 
 * UI跳轉。UI跳轉可以認為是一種特殊的資料傳遞,在實現思路上有啥不同? 
 * 元件的生命週期。我們的目標是可以做到對元件可以按需、動態的使用,因此就會涉及到元件載入、解除安裝和降維的生命週期。 
 * 整合除錯。在開發階段如何做到按需的編譯元件?一次除錯中可能只有一兩個元件參與整合,這樣編譯的時間就會大大降低,提高開發效率。 
 * 程式碼隔離。元件之間的互動如果還是直接引用的話,那麼元件之間根本沒有做到解耦,如何從根本上避免元件之間的直接引用呢?也就是如何從根本上杜絕耦合的產生呢?只有做到這一點才是徹底的元件化。

某個元件module的build.gradle的示例:
if(isRunAlone.toBoolean()){    
  apply plugin: 'com.android.application'
}else{  
  apply plugin: 'com.android.library'
}
.....
resourcePrefix "readerbook_"
  sourceSets {
        main {
            if (isRunAlone.toBoolean()) {
                manifest.srcFile 'src/main/runalone/AndroidManifest.xml'
                java.srcDirs = ['src/main/java','src/main/runalone/java']
                res.srcDirs = ['src/main/res','src/main/runalone/res']
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

支援元件的程式碼資源隔離、單獨除錯、整合除錯、元件互動、UI跳轉、生命週期等完整功能。
android元件化方案- https://github.com/mqzhangw/JIMU

-- Android 元件化 - 路由設計
 頁面跳轉這方面,比如阿里的ARouter, 天貓的統跳協議, Airbnb的DeepLinkDispatch, 藉助註解來完成頁面的註冊,從而很巧妙地實現了路由跳轉。介面解耦又是App架構的重中之重。 統跳協議是天貓App統一跳轉協議,主要負責天貓App介面之間的串聯,也就是介面跳轉服務。
 愛奇藝 Andromeda開源地址- https://gitee.com/bettar/Andromeda.
 Airbnb DeepLinkDispatch- https://github.com/airbnb/DeepLinkDispatch
 愛奇藝釋出重磅開源專案- https://blog.csdn.net/Ch97CKd/article/details/80522954
  目前愛奇藝App中,由於複雜的業務場景,,導致既有單程序的通訊需求,也有跨程序的通訊需求,並且還要支援跨程序通訊中的Callback呼叫,以及全域性的事件匯流排。
 Andromeda:架構的核心就是Dispatcher和RemoteTransfer, Dispatcher負責管理所有程序的業務binder以及各程序中RemoteTransfer的binder; 而RemoteTransfer負責管理它所在程序所有Module的服務binder.
 - 微信Android模組化架構重構實踐(上)中說到的那樣,"我們理解的協議通訊,是指跨平臺/序列化的通訊方式,類似終端和伺服器間的通訊或restful這種。現在這種形式在終端內很常見了。協議通訊具備一種很強力解耦能力,但也有不可忽視的代價。無論什麼形式的通訊,所有的協議定義需要讓通訊兩方都能獲知。通常為了方便會在某個公共區域存放所有協議的定義,這情況和Event引發的問題有點像。另外,協議如果變化了,兩端怎麼同步就變得有點複雜,至少要配合一些框架來實現。在一個應用內,這樣會不會有點複雜?用起來好像也不那麼方便?更何況它究竟解決多少問題呢"。
 - 餓了麼Hermes:原理則是利用動態代理+反射的方式來替換AIDL生成的靜態代理,但是它在跨程序這方面本質上採用的仍然是bindService()的方式.
餓了麼 Hermes的demo請點選- https://github.com/Xiaofei-it/Hermes-IPC-Demo
簡單易用的安卓程序間通訊IPC框架- https://github.com/Xiaofei-it/Hermes
 - 其他元件間通訊方案:DDComponentForAndroid,ModularizationArchitecture
DDComponentForAndroid- https://gitee.com/andli/DDComponentForAndroid
ModularizationArchitecture- https://github.com/wutongke/ModularizationArchitecture
專案Github地址:https://github.com/SpinyTech/ModularizationArchitecture

> 模組化 (自定義路由框架)
  曾經也許你做過這樣的事,將一些公共的程式碼組成獨立的 module 並編譯為 library 供各個子模組或其他專案引用,通常利用這種方式實現專案模組化(小功能獨立拆分)。
 頁面路由模組化的頁面路由功能- https://github.com/chiclaim/android-modularization
 - Android 模組化探索與實踐- https://www.cnblogs.com/baronzhang/p/6861258.html
 關於Android模組化我有一些話不知當講不當講- https://www.jianshu.com/p/910911172243
 - 淺談Android模組化設計(常規思路)- http://blog.csdn.net/weijianfeng1990912/article/details/66475959
 模組化設計輕量級的方案,手淘Atlas和螞蟻金服支付寶MPass這樣大型的容器化方案。模組化的精髓,個人覺得應該就是解耦,所有才有了路由的出現。
 在Android領域的模組化方案,基本都逃不開路由的設計,基本原理:都是用到了intent-filter中的data的host和scheme,借鑑了網路中概念,通過類似url地址的資訊和Activity建立路由對映關係,然後通過,url地址來請求,經過建立的路由對映關係,根據host,scheme進行處理,跳轉對應模組。 所以在Android模組化方案中,大部分設計套路都集中在了 怎麼建立這種路由表了。