項(xiàng)目發(fā)展到一定程度,就必須進(jìn)行模塊的拆分。模塊化是一種指導(dǎo)理念,其核心思想就是分而治之、降低耦合。而在 Android 工程實(shí)踐,目前有兩種途徑,一個(gè)是組件化,一個(gè)是插件化。
組件化開發(fā)
說起組件化少不了提起AS模塊化的概念,其實(shí)兩種方式的本質(zhì)思想是一樣的,都是為了代碼重用和業(yè)務(wù)解耦。
模塊化
模塊(Module),Android Studio提出的概念,它是根據(jù)不同關(guān)注點(diǎn)將原項(xiàng)目中共享的部分或業(yè)務(wù)抽取出來形成獨(dú)立module,這就類似我們集成的第三方庫的SDK。
Module包含兩種格式: application, library。application格式的module就可以打包成一個(gè)apk,一個(gè)library可以形成一個(gè)aar包(類似java中的jar包)。在我們實(shí)際開發(fā)中,通常會抽取第三方庫、使用封裝的網(wǎng)絡(luò)庫、圖片庫、視頻庫、Utils工具類、自定義View 等到一個(gè)共有的common模塊中,其他模塊在配置Gradle依賴后,就能夠調(diào)用這些API。它 相比于包來講,模塊更靈活,耦合更低,隨意插拔,想引入哪個(gè)就引入哪個(gè)。根據(jù)不同的關(guān)注點(diǎn),將一個(gè)項(xiàng)目的可以共享的部分抽取出來,形成獨(dú)立的Module,就是模塊化。
組件化
組件化是基于模塊化的,組件化是建立在模塊化思想上的一次演進(jìn),一個(gè)變種。組件化本來就是模塊化的概念,但是組件化的核心是:模塊角色的可轉(zhuǎn)換性,可以在打包時(shí)是設(shè)置為library,開始調(diào)試運(yùn)行是設(shè)置成application。
通俗的講組件化就是基于可重用的目的,將一個(gè)大的軟件系統(tǒng)按照分離關(guān)注點(diǎn)的形式,拆分成多個(gè)獨(dú)立的組件。 組件的出現(xiàn)是為了解決全局工程中有很多重復(fù)代碼的問題,是為了復(fù)用,而且劃分力度是相對較小的模塊。組件化的另一個(gè)目的是為了解耦,把系統(tǒng)拆分成多個(gè)組件,分離組件邊界和責(zé)任,便于獨(dú)立升級和維護(hù)。
組件化開發(fā)的結(jié)構(gòu)

圖中從上向下分別為應(yīng)用層、組件層,功能基礎(chǔ)層
- 基礎(chǔ)層: 基礎(chǔ)層包含的是一些基礎(chǔ)庫以及對基礎(chǔ)庫的封裝,比如常用的圖片加載,網(wǎng)絡(luò)請求,數(shù)據(jù)存儲操作等等,它往往是一些功能性的,其他模塊或者組件都可以引用同一套基礎(chǔ)庫,這樣不但只需要開發(fā)一套代碼,還解耦了基礎(chǔ)功能和業(yè)務(wù)功能的耦合,在基礎(chǔ)庫變更時(shí)更加容易操作。
- 組件層: 基礎(chǔ)層往上是組件層,組件層就包含就是根據(jù)我們應(yīng)用劃分的業(yè)務(wù)組件,例如登錄模塊,消息模塊等。
- 應(yīng)用層: 工程根據(jù)需要加入自己的業(yè)務(wù)組件。
組件化開發(fā)帶來的優(yōu)點(diǎn):
- 業(yè)務(wù)模塊分開,解耦的同時(shí)也降低了項(xiàng)目的復(fù)雜度,結(jié)構(gòu)非常清晰。
- 開發(fā)調(diào)試時(shí)不需要對整個(gè)項(xiàng)目進(jìn)行編譯,每個(gè)模塊可獨(dú)立編譯,提高了編譯速度。
- 多人合作時(shí)可以只關(guān)注自己的業(yè)務(wù)模塊,把某一業(yè)務(wù)當(dāng)成單一項(xiàng)目來開發(fā),可以提升開發(fā),測試效率。
- 可以靈活的對業(yè)務(wù)模塊進(jìn)行組裝和拆分。
- 避免重復(fù)造輪子,節(jié)省開發(fā)維護(hù)成本;
多個(gè)團(tuán)隊(duì)公用同一個(gè)組件,在一定層度上確保了技術(shù)方案的統(tǒng)一性。
總結(jié):其實(shí)組件化更多的是適合于項(xiàng)目大 但是功能相對集中的一些項(xiàng)目。比如 一個(gè)金融類的App 里面只包含金融的功能,金融功能又會有 借貸,理財(cái),線下交易,把這些模塊抽成單獨(dú)的組件。
插件化開發(fā)
插件化是將一個(gè)apk根據(jù)業(yè)務(wù)功能拆分成不同的子apk(也就是不同的插件),每個(gè)子apk可以獨(dú)立編譯打包,最終發(fā)布上線的是集成后的apk。在apk使用時(shí),每個(gè)插件是動態(tài)加載的,插件也可以進(jìn)行熱修復(fù)和熱更新。它也是屬于模塊化的一種體現(xiàn)。不過它的單位是apk,一個(gè)完整的項(xiàng)目。靈活性在于加載apk,按需下載,動態(tài)更新。
如果一個(gè)應(yīng)用所有的功能是非常多的,比如滴滴、美團(tuán)、支付寶,他們除了一些基礎(chǔ)的業(yè)務(wù)功能,還有其他的業(yè)務(wù)功能,如果都打成一個(gè)apk,文件將非常大,用插件化的方式開發(fā)后,apk只包含基礎(chǔ)的業(yè)務(wù)功能,使用過程中用戶可以按需加載自己需要的功能模塊。
插件化的開發(fā)并沒有一個(gè)官方的插件化方案,它是國內(nèi)提出的一種技術(shù)實(shí)現(xiàn),利用虛擬機(jī)的類的加載機(jī)制實(shí)現(xiàn)的一種技術(shù)手段,往往需要hook一些系統(tǒng)api,而Google從Android9.0開始限制對系統(tǒng)私有api的使用,也就造成了插件化的兼容性問題,現(xiàn)在幾個(gè)流行的插件化技術(shù)框架,都是大廠根據(jù)自己的需求,開源出來的,如滴滴的VirtualAPK,360的RePlugin等。
總結(jié):插件化開發(fā)適合于項(xiàng)目超級大 但是功能相對不集中比如 一個(gè)支付寶App 里面即包含共享單車 也包含 電影票。這種與本業(yè)務(wù)完全不同的 可以做成插件的形式。
插件化和組件化的區(qū)別
| 技術(shù) | 單位 | 實(shí)現(xiàn)內(nèi)容 | 靈活性 | 特性 | 靜動態(tài) |
|---|---|---|---|---|---|
| 組件化 | 組件(module) | 解耦與加快編譯, 隔離不需要關(guān)注的部分 | 按加載時(shí)機(jī)切換,是作為lib,還是apk;組件化能做的只是, 朋友圈已經(jīng)有了,我想單獨(dú)調(diào)試,維護(hù),和別人不耦合。但是和整個(gè)項(xiàng)目還是有關(guān)聯(lián)的。 | 組:每個(gè)組件,可以獨(dú)立編譯,開發(fā);但本質(zhì)上他不是完全獨(dú)立的,例如一個(gè)登錄模塊,它是和整個(gè)項(xiàng)目有關(guān)聯(lián)的,是項(xiàng)目的組成部分 | 編譯期可以動態(tài)的添加和修改,運(yùn)行時(shí)不具備 |
| 插件化 | apk(一個(gè)完整的應(yīng)用) | 解耦與加快編譯,同時(shí)實(shí)現(xiàn)熱插拔也就是熱更新 | 加載的是apk,可以動態(tài)下載,動態(tài)更新,比組件化更靈活;插件化是朋友圈就是一個(gè)app, 我需要整合了,把它整合進(jìn)微信這個(gè)大的app里面 | 插:是獨(dú)立的apk,每個(gè)插件可以作為一個(gè)完全獨(dú)立的apk運(yùn)行,也可以和其他插件集成為大apk。 | 編譯期和運(yùn)行時(shí)都可以動態(tài)的添加和修改,所以它比組件化更靈活 |
插件化和組件化的選擇
理想的代碼組織形式應(yīng)該是插件化的方式,屆時(shí)就具備了完備的運(yùn)行時(shí)動態(tài)化,更靈活,各個(gè)插件的開發(fā)獨(dú)立自主性更強(qiáng)。
但是目前還沒有一個(gè)完美兼容的插件化方案。
選擇插件化需要考慮兩個(gè)方面:
- 兼容性。一是插件化不可避免的去 hook 一些系統(tǒng)的 api,也就不可避免地有兼容性的問題,因此每個(gè)插件化方案需要有專門的團(tuán)隊(duì)去負(fù)責(zé)維護(hù);
- 開發(fā)節(jié)奏。二是從一個(gè)業(yè)務(wù)邏輯復(fù)雜的項(xiàng)目中去拆分插件化需要的時(shí)間可能是非常巨大的,同時(shí)把原有的項(xiàng)目集成到一個(gè)平臺上,需要使用插件化的相關(guān)技術(shù)去修改,對Android四大組件的兼容性,對原來實(shí)現(xiàn)方式的適配都是一個(gè)挑戰(zhàn)。
- 支持性。應(yīng)用市場的支持:目前Google Play是不允許插件化的這種動態(tài)加載,增量更新方式的app上架的,因?yàn)檫@樣會繞過審核,保不齊一些不良 App “掛羊頭賣狗肉”,等用戶下載、安裝 App 之后,熱更新出其他不良功能。目前國內(nèi)市場還沒明文規(guī)定。技術(shù)上的支持:一定程度上說,谷歌是不鼓勵(lì)這種開發(fā)方式的,對私有api的限制以后會越來越嚴(yán)格,現(xiàn)有市場上的框架都是三年之前的。
大多數(shù)情況下,組件化都是一個(gè)不錯(cuò)甚至最佳的選擇,它沒有兼容性,可以更方便地拆分,并且?guī)缀鯖]有技術(shù)障礙,可以更順利地去執(zhí)行。特別是對急需拆分的產(chǎn)品來說,組件化是一個(gè)可退可守的方案,可以更快地執(zhí)行下去,并且將來要是遷移到插件化,組件化拆分也是必經(jīng)的一步。
最后
關(guān)于組件化方面的具體知識,推薦大家去看玉剛說的《Android 組件化最佳實(shí)踐》和楊充的《Android組件化開發(fā)實(shí)踐和案例分享》兩位大佬的兩篇文章,個(gè)人感覺講的很全面,也容易理解。