組件化、ARouter

ARouter參考:
http://www.itdecent.cn/p/6021f3f61fa6
https://juejin.im/entry/59ef1d0c51882578da0d0ea8
組件化參考:
http://www.itdecent.cn/p/1b1d77f58e84
組件化和插件化的最大區(qū)別(應(yīng)該也是唯一區(qū)別)就是組件化在運(yùn)行時(shí)不具備動態(tài)添加和修改組件的功能,但是插件化是可以的。

組件解耦:我們不可以直接使用compile project(:reader)這種方式來引用組件,要實(shí)現(xiàn)組件之間的完全解耦,我們不僅不能直接使用其他組件中的類,最好能根本不了解其中的實(shí)現(xiàn)細(xì)節(jié)。只有這種程度的解耦才是我們需要的。

路由使用場景:

  • 動態(tài)跳轉(zhuǎn)
  • 組件化


    image.png

    最新版的ARouter已經(jīng)可以支持生成路由文檔了
    配置:

javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"]
            }
        }
image.png

什么是組件化?

組件化就是將我們的app工程分隔成若干獨(dú)立的組件,每個(gè)組件可以單獨(dú)運(yùn)行和調(diào)試,組件之間可以使用對方提供的服務(wù),可以相互傳遞數(shù)據(jù),要做到組件可以單獨(dú)運(yùn)行和調(diào)試,所以就必須保證組件之間不能直接進(jìn)行類引用,就是說一個(gè)組件中的類對其他組件來說是透明的,組件應(yīng)該有自己的生命周期(加載、卸載、降維),可以集成調(diào)試。

如何實(shí)現(xiàn)?

* 單獨(dú)運(yùn)行和調(diào)試

1、我們知道在module的gradle文件中,如果gradle依賴的插件是apply plugin: 'com.android.library'的話是不能單獨(dú)運(yùn)行的,如果是apply plugin: 'com.android.application'才可以。
2、單獨(dú)運(yùn)行的module的AndroidManifest文件中都必須有入口Activity
如果保證一個(gè)module在開發(fā)的時(shí)候可以獨(dú)立運(yùn)行,在發(fā)布的時(shí)候又可以集成到主app中呢?
我們可以設(shè)置一個(gè)變量isRunAlone,標(biāo)記當(dāng)前是否需要單獨(dú)調(diào)試,根據(jù)isRunAlone的取值,使用不同的gradle插件(library還是application)和AndroidManifest文件,甚至可以添加Application等Java文件,以便可以做一下初始化的操作。

關(guān)鍵詞:isRunAlone變量、使用不同的gradle插件、使用不同的AndroidManifest文件、可以添加Application等Java文件如果需要做初始化操作的話。(library是沒有Application的)

isRunAlone變量
兩個(gè)AndroidManifest文件
動態(tài)設(shè)置gradle插件

可以添加Application等Java文件如果需要做初始化操作的話
* 組件之間可以使用對方提供的服務(wù)

既然組件之間不能直接進(jìn)行類的引用,那么如何訪問其他組件中的類呢?
在這里我們采用接口+實(shí)現(xiàn)的方式。每個(gè)組件聲明自己提供的服務(wù)Service,這些Service都是一些抽象類或者接口,組件負(fù)責(zé)將這些Service實(shí)現(xiàn)并注冊到一個(gè)統(tǒng)一的路由Router中去。如果要使用某個(gè)組件的功能,只需要向Router請求這個(gè)Service的實(shí)現(xiàn),具體的實(shí)現(xiàn)細(xì)節(jié)我們?nèi)徊魂P(guān)心,只要能返回我們需要的結(jié)果就可以了。這與Binder的C/S架構(gòu)很相像。

1、組件怎么暴露自己提供的服務(wù)呢?在項(xiàng)目中我們簡單起見,專門建立了一個(gè)componentservice的依賴庫,里面定義了每個(gè)組件向外提供的service和一些公共model。
2、服務(wù)的具體實(shí)現(xiàn)是由所屬組件注冊到Router中的,那么是在什么時(shí)間注冊的呢?這個(gè)涉及到組件的生命周期


暴露readcomponent組件提供的服務(wù)

readcomponent組件具體的實(shí)現(xiàn)

app組件如何訪問?
* 組件的生命周期

我們的目標(biāo)是做到對組件按需、動態(tài)的使用,所以組件要有自己的生命周期,加載、卸載和降維。
由于我們要動態(tài)的管理組件,所以給每個(gè)組件添加幾個(gè)生命周期狀態(tài):加載、卸載和降維。為此我們給每個(gè)組件增加一個(gè)ApplicationLike類,里面定義了onCreate和onStop兩個(gè)生命周期函數(shù)。

1、加載:上面講了,每個(gè)組件負(fù)責(zé)將自己的服務(wù)實(shí)現(xiàn)注冊到Router中,其具體的實(shí)現(xiàn)代碼就寫在onCreate方法中。那么主項(xiàng)目調(diào)用這個(gè)onCreate方法就稱之為組件的加載,因?yàn)橐坏﹐nCreate方法執(zhí)行完,組件就把自己的服務(wù)注冊到Router里面去了,其他組件就可以直接使用這個(gè)服務(wù)了。

readcomponent組件的加載與卸載

2、卸載:卸載與加載基本一致,所不同的就是調(diào)用ApplicationLike的onStop方法,在這個(gè)方法中每個(gè)組件將自己的服務(wù)實(shí)現(xiàn)從Router中取消注冊。不過這種使用場景可能比較少,一般適用于一些只用一次的組件。

3、降維:降維使用的場景更為少見,比如一個(gè)組件出現(xiàn)了問題,我們想把這個(gè)組件從本地實(shí)現(xiàn)改為一個(gè)wap頁。降維一般需要后臺配置才生效,可以在onCreate對線上配置進(jìn)行檢查,如果需要降維,則把所有的UI跳轉(zhuǎn)到配置的wap頁上面去。

一個(gè)小的細(xì)節(jié)是,主項(xiàng)目負(fù)責(zé)加載組件,由于主項(xiàng)目和組件之間是隔離的,那么主項(xiàng)目如何調(diào)用組件ApplicationLike的生命周期方法呢?
a.反射
b.基于編譯期字節(jié)碼插入的方式(javassist)
可以用 Javassist 改變 Java 類的字節(jié)碼,而無需真正了解關(guān)于字節(jié)碼或者 Java 虛擬機(jī)(Java virtual machine JVM)結(jié)構(gòu)的任何內(nèi)容

利用反射來實(shí)現(xiàn)
* 集成調(diào)試

每個(gè)組件單獨(dú)調(diào)試通過并不意味著集成在一起沒有問題,因此在開發(fā)后期我們需要把幾個(gè)組件集成到一個(gè)app里面去驗(yàn)證。由于我們上面的機(jī)制保證了組件之間的隔離,所以我們可以任意選擇幾個(gè)組件參與集成。這種按需索取的加載機(jī)制可以保證在集成調(diào)試中有很大的靈活性,并且可以加大的加快編譯速度。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容