網(wǎng)上組件化的文章很多,我本人學習組建化的過程也借鑒了網(wǎng)上先輩們的文章。但大多數(shù)文章都從底層的細枝末節(jié)開始講述,由下而上給人一種這門技術(shù)“博大精深”望而生畏的感覺。而我寫這篇文章的初衷就是由上而下,希望別人在閱讀的過程中能夠覺得“組件化原來也就是這幾個東西”的感覺。
首先我們來看一下組件化項目和傳統(tǒng)項目的區(qū)別
在傳統(tǒng)的項目里
我們通常情況下會有一個commonLib的Libary模塊和一個app的application模塊,業(yè)務(wù)中的邏輯都寫在app中各個功能模塊放到不同的包下。這樣做有以下幾個主要的缺點:
1.無論分包做的再好,隨著項目的增大,項目會逐漸失去層次感,別人來接手的時候會很吃力。
2.我們在debug一個小功能的時候每次修改代碼都需要重新build整個項目,這樣顯的很不合理(不知道AS的熱部署有沒有解決這個問題)
3.多人聯(lián)合開發(fā)在版本管理中很容易出現(xiàn)沖突和代碼覆蓋的問題
在組件化項目中
除了有commonLib和app模塊外,我們按照功能劃分各個業(yè)務(wù)組件模塊(eg:微信可以劃分出chat,contract,find,mine四個大模塊),之前的包變成現(xiàn)在的模塊,增加了層次感;每個功能模塊可以單獨編譯,加快了編譯速度,也為提供單元模塊測試提供了支持;多人開發(fā)只負責自己的模塊,直接避免了版本管理的沖突。

在明白了組件化為我們解決的主要問題后我們來看看需要怎么做
初步實現(xiàn)組建化其實我們最終要解決的問題就只有2個:
1.設(shè)置模塊之間的依賴,且使得業(yè)務(wù)模塊可單獨編譯--通過配置gradle即可解決
2.業(yè)務(wù)模塊之間的頁面跳轉(zhuǎn)以及通信--使用阿里開源的ARouter即可解決
接下來我們具體來看一下如何操作
首先來看一下模塊間依賴的問題
我們可以參照微信的四個模塊(chat,contract,find,mine)來配置
首先我們項目基本結(jié)構(gòu)如下:

我們一共需要建6個module,除了4個功能模塊外還有一個基本的common庫和一個作為啟動的application。
在建好項目后我們需要給4個module配置一個是否單獨編譯的開關(guān):

關(guān)于開關(guān)的配置位置這是一個問題,我們把它添加在gradle.properties文件中,這樣我們每次修改值的時候就可以觸發(fā)gradle的重新構(gòu)建,便于我們單獨編譯module。
我們單獨編譯的開關(guān)配置好了,現(xiàn)在我們來配置6個module之間的依賴關(guān)系:

首先,為了方便各個module之間的交互我們借用了阿里的充分ARouter庫,所以在每個非common的庫(包括主Application)中我都強烈建議加入對ARouter和commonlib的依賴。
其次,4個功能模塊庫我們要為它裝上我們之前配置的是否單獨編譯的開關(guān),我們需要修改如下2個地方:

可以看到我們要修改的就是我紅框框住的地方,當我們的開關(guān)打開的時候,我們就把他當成一個單獨的application來編譯,并且賦予它一個獨一無二的applicationId,這樣我們就可以通過剛剛在gradle.properties中配置的開關(guān)來控制它是否單獨作為一個application來編譯。
而對于我們的入口module--app模塊我們則需要做如下的配置:

我們除了需要配置基本的ARouter以及commonlib依賴以外還需要在app模塊的gradle文件中根據(jù)開關(guān)選擇是否需要依賴我們的功能模塊,這個和各個功能模塊中的配置是相呼應(yīng)的。
而對于其他組件模塊,重復(fù)上述步驟即可完成組件化框架的搭建:

在完成了組件化框架的搭建后我們來簡單的看看框架中一些具有特色的使用方法。
我們首先來看一下各個模塊的頁面間是怎樣跳轉(zhuǎn)的。
我們之前已經(jīng)依賴了ARouter(詳細用法參照https://github.com/alibaba/ARouter),我們要用它來幫我們實現(xiàn)跳轉(zhuǎn)需要以下幾步:

跳轉(zhuǎn)的方法就如同圖2-1中顯示,我們需要標明目標頁面,附帶上要傳送的參數(shù),然后調(diào)用navigation()就可以跳轉(zhuǎn)了,不過有人問目標頁面怎么看著就是一個路徑,它是怎樣定義的?

- 首先要用@Route注解標注頁面,并在path變量中給頁面定義一個路徑
- 對于傳送過來的變量我們直接定義一個同名的字段用@Autowired變量標注,Arouter會對該字段自動賦值
- 最后我們還需要將該頁面注入到ARouter中(原理類似ButterKnife),讓他幫我們完成我們需要的工作
這樣,我們就完成了頁面間的跳轉(zhuǎn)了,是不是比起我們傳統(tǒng)的方法更加簡單合理?
最后我們來看一下組件間如何為彼此提供服務(wù)。
- 這里我想在主module中調(diào)用home組件的sayHello方法來Toast一個人的名字
- 那home里的方法怎樣才能被其他模塊(包括主模塊和其他組件模塊)調(diào)用

首先在commonlib模塊里創(chuàng)建一個暴露方法的接口,并定義接口簽名,同時繼承 Iprovider 接口
然后在home模塊中繼承commonlib里定義的接口,并實現(xiàn)簽名方法。

這里我們同樣使用Arouter的 @Router注解來提供這次服務(wù)的路由。
最后,我們在其他模塊使用 @Autowired 注解就可以調(diào)用該方法了

可以看到我們同樣使用了@Autowired注解來初始定baseService服務(wù),并將頁面注入Arouter中即可調(diào)用服務(wù)中的方法,且對于服務(wù)的依賴是基于接口的依賴,大大提高了其靈活性!
基本組件化框架的搭建就完成了,希望認真看完的朋友能有所收獲!如有不正之處還望指正!
以上項目的碼云地(歡迎參與改進):
https://gitee.com/zsq519/ARouterBaseProject