徹底組件化框架Atoms-mvp

前言

前一段時間看到JessYan的一篇文章,分享他的MVP開源框架,我相信大多數人應該都還有印象,不得不說這個框架確實很棒,感謝JessYan的開源和分享。框架雖然不是項目的核心,但倒是項目的基礎。一個好的項目框架,能幫助你快速地開始企業級項目開發。本人通過對MVPArms的研究考量並結合本身的想法與實際開發過程獲得Atoms-MVP。java

項目已開源Github,徹底組件化的項目框架Atoms-mvpandroid

什麼是組件化

組件化就是將一個完整的App按照關注點分離成多個組件,使得每一個組件成爲單獨的個體,作到組件內部的高聚合和組件之間低耦合。git

爲何咱們要組件化?

宏觀上講,組件化使開發人員更加專一於各模塊的開發,使團隊成員更加方便迭代升級和維護,管理者也更容易統籌帷幄,規範項目層次和結構統一。微觀上講,組件化必將對基礎庫下沉從而提升複用,這也是項目框架演變進化過程當中的的核心思想,對於子模塊一個蘿蔔一個坑,互相不直接依賴,因此不用擔憂變動帶來的風險。從根本上避免一個小小的改動牽連多處須要修改,致使迴歸整個App測試。對於測試同窗而言,能有效的減小測試的時間,原有的業務不須要再次進行功能測試,只需專一於發生變化的業務,以及最終的集成測試便可github

Atoms-mvp組件化過程

1.面向開發過程,維護成本,學習成本。化繁爲簡,less is more,高擴展性爲宗旨,使新手也能快速搭建本身的組件化項目緩存

2.基礎庫下沉,只下沉最核心最必須,毫不拖泥帶水,納污藏穢。bash

2.弱化了Dagger2的使用頻率,由於這對於一些新手來講Dagger2可能不是很好理解,排錯不是很好,可是對於一些頻繁使用到的Dagger代碼我作了優化,省去了大量重複代碼,幫助團隊加快開發速度。網絡

3.網絡請求方面使用Rxjava,okhttp,retrofit組合式框架可是並無使用RxCache處理緩存,由於我以爲這樣會加劇開發成本,增長編碼量和維護成本,其次Okhttp自己是自帶緩存策略的,咱們能夠到後期真正須要的時候再使用緩存框架架構

4.在設計架構時,將最原始,最須要,最重要的庫打入baseLib封裝成基礎庫,好比網絡,support,依賴注入型框架dagger,以及和view相關的butterknife,或者其餘的一些基礎庫,開發者能夠自行擴展。目的是將這些充斥於整個界面相關的業務邏輯集成到最底層。往上一層封裝整個APP須要的公共服務。其中包括CommonSDK用來承上啓下,並提供ARouter路由框架,或者使用360Replugin插件化框架,爲組件之間解耦作鋪墊,開發者可視狀況而定二選其一。以及業務服務庫和公共UI庫,統一整個APP的UI風格方便後期統一調整。再往上就是App的核心組件,各組件依賴公共層,組件之間絕對分離。最後整合在一塊兒完美融合,造成一個APP應用系統框架

本項目特色

1.支持路由框架和插件劃框架好比Arouter,RePlugin等less

2.動態代理Application生命週期,各組件可作具體實現,使得子Module間接地擁有Application,可以在子module中初始化相對當前nodule的的第三方庫。

3.各模塊可配置單獨的ServiceApi,擁有屬於本身獨立的Api接口,同時還支持不一樣host場景

4.各組件數據傳輸面向接口不直接依賴於對象,使組件化解耦更完全,作到徹底組件化。在下面我會一一講到。

組件化的關鍵點

  • 代碼隔離

代碼隔離一樣也是代碼解耦,每一個組件之間代碼互不侵入,互不依賴,團隊之間應具有規範的意識。除了人爲上的約束,IDE工具gradle也爲咱們提供了很好的代碼隔離語法,從AS3.0開始類庫依賴出現了四種新語法以下:

implementation對應之前的compile。與compile的區別在於使用implementation在編譯期間只對當前宿主可見,對其餘宿主隔離。同時它還有一個好處是可以加快編譯速度。打個比方若是宿主使用implementation引用庫的話,當宿主發生變化從新編譯時,庫不須要再編譯,只須要編譯這個宿主。而若是你使用的是compile引用庫的話,那麼二者都須要從新編譯。因此在大部分狀況下推薦使用implementation。從上圖能夠看出,在代碼隔離效果上,runtimeOnly的效果是最好的!因此若是引用子模塊最好選擇runtimeOnly來保證代碼徹底隔離。而compileOnly這個語法就頗有意思了,它的做用是依賴的類庫只參與編譯,而不會打包進Apk。基於這一點,通常狀況下是用來引用編譯時註解的類庫,好比下面這個例子

compileOnly "com.alibaba:arouter-compiler:1.1.4"
  compileOnly "com.jakewharton:butterknife-compiler:8.8.1"
  compileOnly  'com.google.dagger:dagger-compiler:2.15'
複製代碼

這個例子是在組件的gradle文件中,在這裏沒有引用與之相關的庫是由於在組件化項目中各組件都會依賴公共庫,而公共庫會依賴這些註解類庫的相關類庫。因此此時組件應該使用compileOnly依賴註解庫,不須要再引用於編譯註解相關的庫。 若是您在其餘模塊以compile的方式依賴了相同lib,最終在打包過程當中可會出現重複代碼,因此建議您採用compileOnly解決重複依賴的問題

其次我再補充說明一下資源文件隔離。雖然上面解決了代碼隔離可是對於資源文件並無控制,其餘宿主仍是可以訪問下級的資源文件,爲了不編譯時衝突,可爲資源名增長一個前綴,約束資源文件的命名規範。

android {
    resourcePrefix "gank_" //給 Module 內的資源名增長前綴, 避免資源名衝突
}
複製代碼
  • 各模塊可裝配本身的Service域名

有些項目可能有多baseUrl的需求,這種狀況Retrofit官方給了兩種解決方案,以下。

第一種:在 @Get , @Post註解中不只能夠傳相對路徑,還能夠傳全路徑

第二種:將全路徑以參數@Url的形式傳遞給接口

  • 各組件可裝配本身的"Application"

對於有些子模塊來講,它有屬於本身依賴的第三方庫,有些第三方庫須要在Application中初始化,而一個應用程序的Application對象只有一個,每一個組件又所有分離出去了,那麼如何才能各組件共享?在Atoms-MVP中提供瞭解決方案。經過代理方式,委派一個AppDelegate對象去代理Application的生命週期。各各子模塊只需在Manifest文件中定義 meta標籤,指定真實被調用的Application生命週期類名,由Appdelegate建立時經過反射的手段初始化。貼一張圖方便理解

  • 數據傳遞

在組件化項目中,每一個組件都是相對獨立,那麼他們之間如何進行數據傳遞呢?首先想到的是Intent、sp、file、廣播、內容提供者等這些常見的數據傳遞方式,可是剛剛說了組件之間是相對獨立的,不能直接把實體類傳遞過去,由於在徹底解耦的組件化項目中,實體類不會下沉放到公共庫,也不會在多個組件之間存在依賴關係,只出如今於屬於它們本身的組件當中。那麼如何將實體類也徹底解耦呢?Atoms-mvp提供了一套解決方案,每一個組件若是須要對外提供數據傳遞,那麼統一在CommonService組件中聲明向外提供服務接口,具體的實現由須要傳遞數據的組件負責,完成跨模塊數據傳遞。這樣作使得組件之間的交互不直接接觸,避免組件之間的直接依賴關係,只有作到這一點組件之間的才能完全的組件化

總結

Android應用的架構,根據不一樣的應用場景和複雜程度使得技術架構也有不一樣,架構沒有好壞之分,只要適用於本身的業務就是好架構,每一次的重構每一次的更新都是爲了節省人力和成本,提升開發效率。若是您正打算使用組件化框架徹底能夠把個人項目搬過去,改一改包名便可。同時Atoms-mvp也能夠做爲你們在進行組件化時的參考資料,若是您以爲個人文章寫的不錯,對您有幫助請爲我點贊。

Atoms-mvp項目地址:github.com/xwc520/Atom…


參考文檔:

www.jianshu.com/p/1c5afe686…

www.jianshu.com/p/f671dd768…

關於我Vea

簡書:www.jianshu.com/u/9184fed0c…

相關文章
相關標籤/搜索