成熟丰满熟妇高潮XXXXX,人妻无码AV中文系列久久兔费 ,国产精品一国产精品,国精品午夜福利视频不卡麻豆

您好,歡迎來到九壹網(wǎng)。
搜索
您的當(dāng)前位置:首頁MVPArms官方快速組件化方案開源,來自5K star的信賴

MVPArms官方快速組件化方案開源,來自5K star的信賴

來源:九壹網(wǎng)

  • 0

    • 0.1
    • 0.2
      • 0.2.1
      • 0.2.2
      • 0.2.3
    • 0.3
  • 1

    • 1.1
    • 1.2
    • 1.3
    • 1.4
  • 2

    • 2.1
    • 2.2
      • 2.2.1
      • 2.2.2
        • 2.2.2.1
      • 2.2.3
        • 2.2.3.1
        • 2.2.3.2
        • 2.2.3.3
          • 2.2.3.3.1
          • 2.2.3.3.2
          • 2.2.3.3.3
    • 2.3
      • 2.3.1
      • 2.3.2
      • 2.3.3
      • 2.3.4
      • 2.3.5
    • 2.4
      • 2.4.1
      • 2.4.2
      • 2.4.3
  • 3

    • 3.1
    • 3.2
    • 3.3
    • 3.4
    • 3.5
    • 3.6

0 前言

從兩年前開源至今, 已經(jīng)累積了 5k star, 獲得了上千個商業(yè)項目的信賴和認(rèn)可

回顧兩年前, 那時 MVPArms 還沒誕生, MVP、Dagger2RxjavaRetrofit 這些技術(shù)在國內(nèi)才剛剛開始流行, 在網(wǎng)上能搜索到的中文學(xué)習(xí)資料遠(yuǎn)沒有現(xiàn)在這么豐富, 特別是 Dagger, 在網(wǎng)上能搜索到的文章甚至有很多講的是 SquareDagger1, 學(xué)習(xí)資料的匱乏加上 Dagger2 本身就是塊硬骨頭, 讓本人在學(xué)習(xí)的道路上不知道多走了多少彎路

從那時開始, 讓初學(xué)者都能夠快速搭建一個 MVP + Dagger2 + Retrofit + Rxjava 項目的種子就已經(jīng)深埋在心中, 后面經(jīng)過不懈的努力, MVPArms 終于誕生并開源了, 開源以后只是一直堅持將 代碼, 注釋文檔 做到極致, 沒想到的是, MVPArms 能發(fā)展到如今的體量, 感謝開源!

0.1 起源

這是 MVPArms 的起源, ArmsComponent 的起源同樣相似, 從去年開始, 組件化逐漸火熱起來, 本人也在去年年初開始在公司項目中進(jìn)行組件化, 一切還算順利

那時同樣的種子繼續(xù)埋在了心中, 我想讓剛剛接觸組件化的初學(xué)者也能快速搭建一個中小型的組件化項目, 經(jīng)過一年的不斷優(yōu)化, 終于決定將其開源(MVPArms 官方組件化方案 ArmsComponent)

0.2 組件化方案分析

看了很多組件化方案, 所以總結(jié)了在組件化中很重要的三個大點:

0.2.1 業(yè)務(wù)組件的劃分和代碼隔離

先說第三點 業(yè)務(wù)組件的劃分和代碼隔離, 現(xiàn)在大部分的文章都圍繞著這點, 我這里發(fā)表下個人的觀點, 第三點確實是很重要的一點, 不管是大廠的方案還是小廠的方案都有借鑒之處, 但是這點也是最不可能討論出最終結(jié)果和統(tǒng)一解決方案的一點

每個公司、每個項目的情況都不一樣, 大廠的方案真的適合您嗎? 不一定, 大廠幾十個業(yè)務(wù)群, 幾百號開發(fā)人員, 他們的組織結(jié)構(gòu)和項目規(guī)模都不是普通公司能比擬的, 如果伸拉硬套他們的方案, 進(jìn)行更嚴(yán)格更細(xì)粒度的代碼隔離, 可能產(chǎn)出的價值還不及您先前付出的代價, 帶來效率的降低, 所以根據(jù)項目的實際情況做出靈活的調(diào)整才是項目負(fù)責(zé)人最應(yīng)該干的事, 這點我在后面會有詳細(xì)的介紹

0.2.2 路由框架

陸續(xù)也有很多組件化方案開源自己的 路由框架, 是個很不錯的開始, 我覺得大家寫的都不錯, 各有各的優(yōu)勢, 本方案也決定用別人的 路由框架, 自己寫的原理也差不多, 還不一定比別人考慮的完善, 還要自己維護(hù), 為什么不選擇一個成熟穩(wěn)定的呢?

0.2.3 基礎(chǔ)庫

很多組件化文章只是在講如何拆分以及封裝基礎(chǔ)庫, 但是至今沒看到有哪個組件化方案開源過完整的基礎(chǔ)庫的, 我猜測原因可能是, 組件化方案都是從商業(yè)項目不斷的業(yè)務(wù)迭代中逐漸完善的, 基礎(chǔ)庫也屬于公司的核心機密, 所以不可能開源

但是基礎(chǔ)庫尤其重要, 特別是兼容組件化的基礎(chǔ)庫, 這關(guān)乎到組件化方案的根基, 根基都沒有, 何談其他更高級的功能? 但是從封裝到完善一個兼容組件化的基礎(chǔ)庫是需要很長時間的, 大多數(shù)中小公司是不愿意投入這個成本的

0.3 ArmsComponent 的優(yōu)勢

ArmsComponent 擁有一鍵自動生成組件功能, , 雖然一鍵搭建功能讓新手也可以一秒開始組件化項目, 但本方案還是提供有上萬字的詳細(xì)文檔讓您可以更深入的了解本方案, 并且 JessYan 鄭重承諾, ArmsComponent 將和 MVPArms 一起持續(xù)維護(hù)下去, ArmsComponent 絕對是一個真正用心對待的組件化方案

MVPArms 是一個開源兩年, 成熟穩(wěn)定, 涵蓋大量主流技術(shù)且兼容組件化的基礎(chǔ)庫, MVPArms 使得 ArmsComponent 成為了唯一提供完整基礎(chǔ)庫的組件化方案, 這就是 ArmsComponent 相對于其他組件化方案最大的優(yōu)勢

因為有了 基礎(chǔ)庫 的存在, 再加上已有的 路由框架, 組件化中的三個大點就已經(jīng)占有兩個(業(yè)務(wù)組件的劃分和代碼隔離 在后面會有介紹), 因此使用 ArmsComponent 啟動一個新項目, 即可快速進(jìn)行組件化, 將 Demo (組件化項目雛形) 克隆下來后, 稍作修改, 馬上就可以投入到業(yè)務(wù)的開發(fā)之中

ArmsComponent 對于新項目以及已經(jīng)開始使用 MVPArms 的項目將會更加便捷, 有著優(yōu)于其他組件化方案的體驗, 對于那些網(wǎng)絡(luò)請求, 圖片加載等基礎(chǔ)功能亂七八糟散落到項目各處, 沒有統(tǒng)一抽離出來的舊項目, 建議直接使用 MVPArms, 開始組件化

如果您不想使用 MVPArms, 覺得接入成本太大, 沒關(guān)系, 借鑒下 和 的代碼, 嘗試改造自己的項目, 也是個不錯的選擇

1 簡介

好了, 進(jìn)入正題!

1.1 什么是組件化?

組件化簡單概括就是把一個功能完整的 App 或模塊拆分成多個子模塊, 每個子模塊可以編譯和運行, 也可以任意組合成另一個新的 App 或模塊, 每個模塊即不相互依賴但又可以相互交互, 遇到某些特殊情況甚至可以升級或者降級

1.2 為什么要組件化?

現(xiàn)在的項目隨著需求的增加規(guī)模變得越來越大, 規(guī)模的增大帶來了很多煩惱, 各種業(yè)務(wù)錯中復(fù)雜的交織在一起, 每個業(yè)務(wù)模塊之間, 代碼沒有約束, 帶來了代碼邊界的模糊, 代碼沖突時有發(fā)生, 更改一個小問題可能引起一些新的問題, 牽一發(fā)而動全身, 增加一個新需求, 瞻前顧后的熟悉了大量前輩們寫的代碼后才敢動手, 編譯時間也不在斷增加, 開發(fā)效率極度的下降, 在這種情況下組件化的出現(xiàn)就是為了解決以上的煩惱

1.3 分析現(xiàn)有的組件化方案

很多大廠的組件化方案是以 多工程 + 多 Module 的結(jié)構(gòu)(微信, 美團(tuán)等超級 App 更是以 多工程 + 多 Module + 多 P 工程(以頁面為單元的代碼隔離方式) 的三級工程結(jié)構(gòu)), 使用 Git Submodule 創(chuàng)建多個子倉庫管理各個模塊的代碼, 并將各個模塊的代碼打包成 AAR 上傳至私有 Maven 倉庫使用遠(yuǎn)程版本號依賴的方式進(jìn)行模塊間代碼的隔離

1.4 如何選擇組件化方案?

按照康威定律, 系統(tǒng)架構(gòu)的設(shè)計需要根據(jù)組織間的溝通結(jié)構(gòu), 因為現(xiàn)在大部分項目的規(guī)模和開發(fā)人員的數(shù)量以及結(jié)構(gòu)還不足以需要某些大廠發(fā)布的組件化方案支撐(大廠的組織結(jié)構(gòu)和項目規(guī)模都非常龐大, 他們的方案不一定完全適合所有公司的項目), 進(jìn)行更嚴(yán)格更細(xì)粒度的代碼間以及模塊間的隔離, 盲目的使用某些組件化方案, 可能會帶來開發(fā)效率降低, 開發(fā)成本遠(yuǎn)大于收益等情況, 性價比變低, 作為項目負(fù)責(zé)人, 應(yīng)該根據(jù)項目目前的規(guī)模以及開發(fā)人員的組織結(jié)構(gòu)去選擇目前最適合的組件化方案, 做到以項目實際情況去制定技術(shù)方案, 而不是盲目跟隨某些大廠的技術(shù)方案讓項目和開發(fā)人員花費大量時間去調(diào)整和適應(yīng)

2 組件化方案描述

ArmsComponent 目前采用的是 單工程 + 多 Module 的結(jié)構(gòu), 由于 Demo 較小僅僅為了展示基本規(guī)范, 所以也只是采用源碼依賴并沒有做到遠(yuǎn)程版本號依賴組件, 代碼管理也只是采用 單倉庫 + 多分支 的方式, 這樣也是對于開發(fā)初期, 項目規(guī)模還較小, 開發(fā)人員也較少時, 開發(fā)效率較高的方案, 如果您的項目規(guī)模較大, 開發(fā)人員眾多, 就可以采用上面提到的 多工程 + 多 Module, 并使用私有 Maven 倉庫管理組件版本

世界上沒有一個方案可以完美到兼顧所有情況, 并且還滿足所有人, 所有項目的需求, 所以項目負(fù)責(zé)人必須按照項目實際情況做出靈活的調(diào)整, 才能做出最適合自家項目的方案

2.1 架構(gòu)圖一覽

ArmsComponent 組件化架構(gòu)圖

2.2 架構(gòu)圖詳解

目前架構(gòu)一共分為三層, 從低到高依次是基礎(chǔ)層, 業(yè)務(wù)層和宿主層, 由于目前項目較小人員較少所以三層都集中在一個工程中, 但您可以根據(jù)項目的規(guī)模和開發(fā)人員的數(shù)量拆分成多個工程協(xié)同開發(fā)

2.2.1 宿主層

宿主層位于最上層, 主要作用是作為一個 App 殼, 將需要的模塊組裝成一個完整的 App, 這一層可以管理整個 App 的生命周期(比如 Application 的初始化和各種組件以及三方庫的初始化)

2.2.2 業(yè)務(wù)層

業(yè)務(wù)層位于中層, 里面主要是根據(jù)業(yè)務(wù)需求和應(yīng)用場景拆分過后的業(yè)務(wù)模塊, 每個模塊之間互不依賴, 但又可以相互交互, 比如一個商城 App搜索, 訂單, 購物車, 支付 等業(yè)務(wù)模塊組成

Tips: 每個業(yè)務(wù)模塊都可以擁有自己獨有的 SDK 依賴和自己獨有的 UI 資源 (如果是其他業(yè)務(wù)模塊都可以通用的 SDK 依賴 和 UI 資源 就可以將它們抽離到 和 中)

2.2.2.1 業(yè)務(wù)模塊的拆分

寫業(yè)務(wù)之前先不要急著動手敲碼, 應(yīng)該先根據(jù)初期的產(chǎn)品需求到后期的運營規(guī)劃結(jié)合起來清晰的梳理一下業(yè)務(wù)在未來可能會發(fā)生的發(fā)展, 確定業(yè)務(wù)之間的邊界, 以及可能會發(fā)生的變化, 最后再確定下來真正需要拆分出來的業(yè)務(wù)模塊再進(jìn)行拆分

2.2.3 基礎(chǔ)層

基礎(chǔ)層位于最底層, 里面又包括 核心基礎(chǔ)業(yè)務(wù)模塊、公共服務(wù)模塊、 基礎(chǔ) SDK 模塊, 核心基礎(chǔ)業(yè)務(wù)模塊公共服務(wù)模塊 主要為業(yè)務(wù)層的每個模塊服務(wù), 基礎(chǔ) SDK 模塊 含有各種功能強大的團(tuán)隊自行封裝的 SDK 以及第三方 SDK, 為整個平臺的基礎(chǔ)設(shè)施建設(shè)提供動力

2.2.3.1 核心基礎(chǔ)業(yè)務(wù)

核心基礎(chǔ)業(yè)務(wù)業(yè)務(wù)層 的每個業(yè)務(wù)模塊提供一些與業(yè)務(wù)有關(guān)的基礎(chǔ)服務(wù), 比如在項目中以用戶角色分為 2 個端口, 用戶可以扮演多個角色, 但是在線上只能同時操作一個端口的業(yè)務(wù), 這時每個端口都必須提供一個角色切換的功能, 以供用戶隨時在多個角色中切換, 這時在項目中就需要提供一個用于用戶自由切換角色的管理類作為 核心基礎(chǔ)業(yè)務(wù) 被這 2 個端口所依賴(類似 拉勾, Boss 直聘等 App 可以在招聘者和應(yīng)聘者之間切換)

核心基礎(chǔ)業(yè)務(wù) 的劃分應(yīng)該遵循是否為業(yè)務(wù)層大部分模塊都需要的基礎(chǔ)業(yè)務(wù), 以及一些需要在各個業(yè)務(wù)模塊之間交互的業(yè)務(wù), 都可以劃分為 核心基礎(chǔ)業(yè)務(wù)

2.2.3.2 公共服務(wù)

公共服務(wù) 是一個名為 CommonServiceModule, 主要的作用是用于 業(yè)務(wù)層 各個模塊之間的交互(自定義方法和類的調(diào)用), 包含自定義 Service 接口, 和可用于跨模塊傳遞的自定義類

主要流程是:

提供服務(wù)的業(yè)務(wù)模塊:

在公共服務(wù)(CommonService) 中聲明 Service 接口 (含有需要被調(diào)用的自定義方法), 然后在自己的模塊中實現(xiàn)這個 Service 接口, 再通過 ARouter API 暴露實現(xiàn)類

使用服務(wù)的業(yè)務(wù)模塊:

通過 ARouterAPI 拿到這個 Service 接口(多態(tài)持有, 實際持有實現(xiàn)類), 即可調(diào)用 Service 接口中聲明的自定義方法, 這樣就可以達(dá)到模塊之間的交互

跨模塊傳遞的自定義類:

公共服務(wù) 中定義需要跨模塊傳遞的自定義類后 (Service 中的自定義方法和 EventBus 中的事件實體類都可能需要用到自定義類), 就可以通過 ARouter API, 在各個模塊的頁面之間跨模塊傳遞這個自定義對象 (ARouter 要求在 URL 中使用 Json 參數(shù)傳遞自定義對象必須實現(xiàn) SerializationService 接口)

Tips: 建議在 CommonService 中給每個需要提供服務(wù)的業(yè)務(wù)模塊都建立一個單獨的包, 然后在這個包下放 Service 接口 和 需要跨模塊傳遞的自定義類, 這樣更好管理

掌握公共服務(wù)層的用法最好要了解 ARouter 的 API

2.2.3.3 基礎(chǔ) SDK

基礎(chǔ) SDK 是一個名為 CommonSDKModule, 其中包含了大量功能強大的 SDK, 提供給整個架構(gòu)中的所有模塊

2.2.3.3.1 MVPArms

MVPArms 是整個基礎(chǔ)層中最重要的模塊, 可謂是整個組件化架構(gòu)中的心臟, 里面提供了開發(fā)一個完整項目所必須的一整套 APISDK, 是整個項目的腳手架, 我用它來統(tǒng)一整個組件化方案的基礎(chǔ)設(shè)施, 使每一個模塊更加健壯, 因為有了 MVPArms, 使得 ArmsComponent 成為了唯一提供完整基礎(chǔ)框架的組件化方案, 所以學(xué)習(xí) ArmsComponent 之前必須先學(xué)會 MVPArms

學(xué)習(xí) MVPArms 時請按以下排列順序依次學(xué)習(xí):

1.

2.

3.

2.2.3.3.2 UI 組件

基礎(chǔ) SDK 中的 UI 組件 是一個名為 CommonResModule, 主要放置一些業(yè)務(wù)層可以通用的與 UI 有關(guān)的資源供所有業(yè)務(wù)層模塊使用, 便于重用、管理和規(guī)范已有的資源

Tips: 值得注意的是, 業(yè)務(wù)層的某些模塊如果出現(xiàn)有資源名命名相同的情況 (如兩個圖片命名相同), 當(dāng)在宿主層集成所有模塊時就會出現(xiàn)資源沖突的問題, 這時注意在每個模塊的 build.gradle 中使用 resourcePrefix 標(biāo)簽給每個模塊下的資源名統(tǒng)一加上不同的前綴即可解決此類問題

android {
    defaultConfig {
        minSdkVersion rootProject.ext.android["minSdkVersion"]
        ...
    }
    resourcePrefix "public_"
}
復(fù)制代碼

可以放置的資源類型有:

  • 通用的 Style, Theme
  • 通用的 Layout
  • 通用的 Color, Dimen, String
  • 通用的 Shape, Selector, Interpolator
  • 通用的 圖片資源
  • 通用的 動畫資源
  • 通用的 自定義 View
  • 通用的第三方 自定義 View

2.2.3.3.3 其他 SDK

其他 SDK 主要是 基礎(chǔ) SDK 依賴的一些業(yè)務(wù)層可以通用的 第三方庫第三方 SDK (比如 ARouter, 騰訊 X5 內(nèi)核), 便于重用、管理和規(guī)范已有的 SDK 依賴

2.3 跨組件通信

2.3.1 為什么需要跨組件通信?

因為各個業(yè)務(wù)模塊之間是各自的, 并不會存在相互依賴的關(guān)系, 所以一個業(yè)務(wù)模塊是訪問不了其他業(yè)務(wù)模塊的代碼的, 如果想從 A 業(yè)務(wù)模塊的 A 頁面跳轉(zhuǎn)到 B 業(yè)務(wù)模塊的 B 頁面, 光靠模塊自身是不能實現(xiàn)的, 所以這時必須依靠外界的其他媒介提供這個跨組件通信的服務(wù)

2.3.2 跨組件通信場景

跨組件通信主要有以下兩種場景:

  • 第一種是組件之間的頁面跳轉(zhuǎn) (ActivityActivity, FragmentFragment, ActivityFragment, FragmentActivity) 以及跳轉(zhuǎn)時的數(shù)據(jù)傳遞 (基礎(chǔ)數(shù)據(jù)類型和可序列化的自定義類類型)

  • 第二種是組件之間的自定義類和自定義方法的調(diào)用(組件向外提供服務(wù))

2.3.3 跨組件通信方案

其實以上兩種通信場景甚至其他更高階的功能在 ARouter 中都已經(jīng)被實現(xiàn), ARouterAlibaba 開源的一個 Android 路由中間件, 可以滿足很多組件化的需求, 也是作為本方案中比較重要的一環(huán), 需要認(rèn)真看下文檔, 了解下基本使用

關(guān)于跨組件通信框架, 本方案不做封裝, 專業(yè)的事交給專業(yè)的人做, 此類優(yōu)秀框架為數(shù)眾多, 各有特點, 可以根據(jù)您的需求選擇您喜歡的框架, 不一定非得是 ARouter, 選擇 ARouter 也是因為 Alibaba 出品, 開源時間較長, 使用者眾多, 相對穩(wěn)定, 出現(xiàn)問題比較好溝通

2.3.4 跨組件通信方案分析

第一種組件之間的頁面跳轉(zhuǎn)不需要過多描述了, 算是 ARouter 中最基礎(chǔ)的功能, API 也比較簡單, 跳轉(zhuǎn)時想傳遞不同類型的數(shù)據(jù)也提供有相應(yīng)的 API (如果想通過在 URL 中使用 Json 參數(shù)傳遞自定義對象, 需要實現(xiàn) SerializationService, 詳情請查閱 );

第二種組件之間的自定義類和自定義方法的調(diào)用要稍微復(fù)雜點, 需要 ARouter 配合架構(gòu)中的 公共服務(wù)(CommonService) 實現(xiàn), 主要流程在 中已有介紹, 這里我畫了個示意圖, 以便大家更好理解

跨組件通信示意圖

此種服務(wù)提供方式叫作 接口下沉, 看圖的同時請配合閱讀 中的主要流程便于理解

本方案中還提供有 EventBus 來作為服務(wù)提供的另一種方式, 大家知道 EventBus 因為其解耦的特性, 如果被濫用的話會使項目調(diào)用層次結(jié)構(gòu)混亂, 不便于維護(hù)和調(diào)試, 所以本方案使用 其獨有的 Tag, 可以在開發(fā)時更容易定位發(fā)送事件和接受事件的代碼, 如果以組件名來作為 Tag 的前綴進(jìn)行分組, 也可以更好的統(tǒng)一管理和查看每個組件的事件, 當(dāng)然也不建議大家過多使用 EventBus

Tips: 每個跨組件通信框架提供服務(wù)的方式都不同, 您也可以選擇其他框架的服務(wù)提供方式

2.3.5 跨組件傳遞復(fù)雜數(shù)據(jù)格式

在一般情況下基本數(shù)據(jù)類型就可以滿足大多數(shù)跨組件傳遞數(shù)據(jù)的需求, 但是在某些情況下也會需要傳遞復(fù)雜的自定義數(shù)據(jù)類型, 傳遞自定義類型在方案中也提供有兩種方式:

第一種在 中已提及, 就是在 公共服務(wù) (CommonService) 中定義這個自定義類

第二種方式也比較簡單, 直接通過解析 Json 字符串就可以傳遞

2.4 組件的生命周期

每個組件 (模塊) 在測試階段都可以運行, 在運行時每個組件都可以指定自己的 Application, 這時組件自己管理生命周期就輕而易舉, 比如想在 onCreate 中初始化一些代碼都可以輕松做到, 但是當(dāng)進(jìn)入集成調(diào)試階段, 組件自己的 Application 已不可用, 每個組件都只能依賴于宿主的生命周期, 這時每個組件如果需要初始化自己獨有的代碼, 該怎么辦?

2.4.1 問題分析

在集成調(diào)試階段, 宿主依賴所有組件, 但是每個組件卻不能依賴宿主, 意思是每個組件根本不知道自己的宿主是誰, 當(dāng)然也就不能通過訪問代碼的方式直接調(diào)用宿主的方法, 從而在宿主的生命周期里加入自己的邏輯代碼

如果直接將每個模塊的初始化代碼直接復(fù)制進(jìn)宿主的生命周期里, 這樣未免過于暴力, 不僅代碼耦合不易擴展, 而且代碼還極易沖突, 所以修改宿主源碼的方式也不可行

所以有沒有什么方法可以讓每個組件在集成調(diào)試階段都可以獨自管理自己的生命周期呢?

其實解決思路很簡單, 無非就是在開發(fā)時讓每個組件可以管理自己的生命周期, 在運行時又可以讓每個組件的生命周期與宿主的生命周期進(jìn)行合并 (在不修改或增加宿主代碼的情況下完成)

2.4.2 可行方案分析

想在不更改宿主代碼的情況下在宿主的生命周期中動態(tài)插入每個組件的代碼, 這倒有點像 AOP 的意思

現(xiàn)有的解決方案大概有三種:

  1. 在基礎(chǔ)層中提供一個用于管理組件生命周期的管理類, 每個組件都手動將自己的生命周期實現(xiàn)類注冊進(jìn)這個管理類, 在集成調(diào)試時, 宿主在自己的 Application 對應(yīng)生命周期方法中通過管理類去遍歷調(diào)用注冊的所有生命周期實現(xiàn)類即可

  2. 使用 AnnotationProcessor 解析注解在編譯期間生成源代碼自動注冊所有組件的生命周期實現(xiàn)類, 然后宿主再在對應(yīng)的生命周期方法中去調(diào)用

  3. 使用 Javassist 在編譯時動態(tài)修改 class 文件, 直接在宿主的對應(yīng)生命周期方法中插入每個組件的生命周期邏輯

我最后還是選擇了第一種方法, 因為后面兩種方法雖然使用簡單, 還可以自動化的完成所有操作, 非常炫酷, 但是這兩種方法技術(shù)實現(xiàn)復(fù)雜, 在不同的 Gradle 版本中還會出現(xiàn)兼容性問題影響整個項目的開發(fā)進(jìn)度, 較難維護(hù), 還會增加編譯時間

選擇第一種方法雖然增加了幾步操作, 但是簡單明了, 便與理解和維護(hù), 后續(xù)人員加入也可以很快上手, 不受 Gradle 版本的影響, 也不會增加編譯時間

2.4.3 最終執(zhí)行方案

第一種方案具體原理也沒什么好說的, 比較簡單, 大概就是在基礎(chǔ)層中定義有生命周期方法 (attachBaseContext(), onCreate() ...) 的接口, 每個組件實現(xiàn)這個接口, 然后將實現(xiàn)類注冊進(jìn)基礎(chǔ)層的管理器, 宿主通過管理器在對應(yīng)的生命周期方法中調(diào)用所有的接口實現(xiàn)類, 典型的觀察者模式, 類似注冊點擊事件

MVPArms 中這種方案的實現(xiàn)類叫作 ConfigModule, 每個組件都可以聲明一個或多個 ConfigModule 實現(xiàn)類, 內(nèi)部實現(xiàn)較為復(fù)雜, 實現(xiàn)原理是 反射 + 代理 + 觀察者, 這個類也是整個 MVPArms 框架提供給開發(fā)者最重要的類

它可以給 MVPArms 框架配置大量的自定義參數(shù), 包括項目中所有生命周期的管理 (Application, Activity, Fragment), 項目中所有網(wǎng)絡(luò)請求的管理 (Retrofit, Okhttp, Glide),為框架提供了極大的擴展性, 使框架更加靈活

3 項目講解

3.1 如何讓組件運行?

#isBuildModule 為 true 時可以使每個組件運行, false 則可以將所有組件集成到宿主 App 中
isBuildModule=true
復(fù)制代碼

3.2 配置 AndroidManifest

由于組件在運行時和集成到宿主時可能需要 AndroidManifest 配置不一樣的參數(shù), 比如組件在運行時需要其中的一個 Activity 配置了 <action android:name="android.intent.action.MAIN"/> 作為入口, 而當(dāng)組件集成到宿主中時, 則依賴于宿主的入口, 所以不需要配置 <action android:name="android.intent.action.MAIN"/>, 這時我們就需要兩個不同的 AndroidManifest 應(yīng)對不同的情況

在組件的 build.gradle 中加入以下代碼, 即可指定不同的 AndroidManifest, 具體請看項目代碼

android {
	sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
            if (isBuildModule.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }
}
復(fù)制代碼

3.3 配置 ConfigModule(GlobalConfiguration)

ConfigModule 在 中提到過, GlobalConfiguration 是實現(xiàn)類, 他可以給框架配置大量的自定義參數(shù)

項目 CommonSDK 中提供有一個 GlobalConfiguration 用于配置每個組件都會用到的公用配置信息, 但是每個組件可能都需要有一些私有配置, 比如初始化一些特有屬性, 所以在每個組件中也需要實現(xiàn) ConfigModule, 具體請看項目代碼

需要注意的是, 在 中提到過組件在運行時和集成到宿主時所需要的配置是不一樣的, 當(dāng)組件在運行時需要在 AndroidManifest 中聲明自己私有的 GlobalConfigurationCommonSDK 公有的 GlobalConfiguration, 但在集成到宿主時, 由于宿主已經(jīng)聲明了 CommonSDK 的公有 GlobalConfiguration, 所以在 AndroidManifest 只需要聲明自己私有的 GlobalConfiguration, 這里也說明了 AndroidManifest 在不同的情況需要做出不同的配置

3.4 RouterHub

所以每個組件使用自己的組件名作為 Group 是比較好的選擇, 畢竟組件不會重名

3.5 EventBusHub

AndroidEventBus 作為本方案提供的另一種跨組件通信方式 (第一種跨組件通信方式是 ), AndroidEventBusgreenrobotEventBus 多了一個 Tag, 在組件化中更容定位和管理事件

EventBusHub 用來定義 AndroidEventBusTag 字符串, 以組件名作為 Tag 前綴, 對每個組件的事件進(jìn)行分組

Tag 的命名規(guī)則為 組件名 + 頁面名 + 動作, 比如需要使用 AndroidEventBus 通知訂單組件的訂單詳情頁進(jìn)行刷新, 可以將這個刷新方法的 Tag 命名為 "order/OrderDetailActivity/refresh"

Tips: 基礎(chǔ)庫中的 EventBusHub 僅用來存放需要跨組件通信的事件的 Tag, 如果某個事件只想在組件內(nèi)使用 AndroidEventBus 進(jìn)行通信, 那就讓組件自行管理這個事件的 Tag

3.6 在項目中使用多個不同的域名

在項目中, 有 知乎 、干貨集中營稀土掘金 三個模塊, 這三個模塊網(wǎng)絡(luò)接口的域名都不一樣, 但是在項目中卻可以統(tǒng)一使用框架提供的同一個 Retrofit 進(jìn)行網(wǎng)絡(luò)請求, 這是怎么做到的呢? 這是采用本人的另一個庫 , 它可以使 Retrofit 同時支持多個 BaseUrl 以及動態(tài)改變 BaseUrl


Hello 我叫Jessyan,如果您喜歡我的文章,可以在以下平臺關(guān)注我

  • GitHub:
  • 掘金:
  • 簡書:
  • 微博:

-- The end

因篇幅問題不能全部顯示,請點此查看更多更全內(nèi)容

Copyright ? 2019- 91gzw.com 版權(quán)所有 湘ICP備2023023988號-2

違法及侵權(quán)請聯(lián)系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市萬商天勤律師事務(wù)所王興未律師提供法律服務(wù)