概述
項(xiàng)目發(fā)展到一定階段使碾,隨著需求的增加以及需求的頻繁變更种远,項(xiàng)目會(huì)越來(lái)越大涩澡,耦合會(huì)越來(lái)越多,開(kāi)發(fā)效率也會(huì)降低坠敷,這個(gè)時(shí)候需要做的就是進(jìn)行模塊拆分妙同,官方的說(shuō)法就是組件化。
App基本框架模型
任意一個(gè)App抽象出來(lái)膝迎,可以得到上圖模型粥帚。這個(gè)模型包括兩大部分:基礎(chǔ)框架和業(yè)務(wù)。下面從模型介紹限次、生命周期茎辐、組件間通信三個(gè)方面來(lái)進(jìn)行闡述。
1. 模型介紹
(1)一個(gè)完整的App由基礎(chǔ)框架(App Framework)和業(yè)務(wù)組件(Business)組成掂恕。
(2)Business指的是具體業(yè)務(wù)線的業(yè)務(wù)拖陆。App Framework是基礎(chǔ)框架,不存在業(yè)務(wù)邏輯懊亡,業(yè)務(wù)線必須基于這個(gè)框架開(kāi)發(fā)依啰,可以理解為所謂的殼工程。這個(gè)App Framework由3部分組成:基礎(chǔ)功能組件店枣、基礎(chǔ)業(yè)務(wù)組件和Framework速警√居基礎(chǔ)功能組件指的是網(wǎng)絡(luò)層、數(shù)據(jù)庫(kù)闷旧、日志等基礎(chǔ)服務(wù)长豁;基礎(chǔ)業(yè)務(wù)組件指的是上層業(yè)務(wù)需要用到的比較獨(dú)立的基礎(chǔ)業(yè)務(wù)服務(wù),如登錄組件忙灼、支付組件匠襟、評(píng)論組件等;Framework負(fù)責(zé)基礎(chǔ)功能組件和基礎(chǔ)業(yè)務(wù)組件的調(diào)度和生命周期管理该园,因?yàn)榍懊嬲f(shuō)的組件都是獨(dú)立無(wú)連接的酸舍,因此運(yùn)行不起來(lái),要想形成一個(gè)有機(jī)整體正常運(yùn)行起來(lái)里初,需要依托于Framework啃勉,實(shí)現(xiàn)組件生命周期管理和調(diào)度。
(3)遵循向下依賴關(guān)系双妨。即Business整體依賴于App Framework淮阐。而App Framework中Framework類(lèi)似于一個(gè)調(diào)度器,它是基于基礎(chǔ)功能組件和基礎(chǔ)業(yè)務(wù)組件的刁品∑兀基礎(chǔ)業(yè)務(wù)組件依賴于基礎(chǔ)功能組件。我認(rèn)為這種向下依賴關(guān)系可以顯式依賴哑诊,即可以直接調(diào)用来农。
(4)關(guān)于平級(jí)依賴剔桨。通常情況下App Framework應(yīng)該盡量避免平級(jí)依賴。而對(duì)于上層業(yè)務(wù)組件平級(jí)之間的依賴是很常見(jiàn)的。這涉及到組件間通信郭变,屬于基礎(chǔ)框架中的Framework的職責(zé)医瘫,通常做法是提供一個(gè)Router或者Mediator進(jìn)行中轉(zhuǎn)萨蚕。
2. 生命周期
曾經(jīng)看過(guò)一位前輩的文章担猛,加上自己的一點(diǎn)理解傅联,來(lái)闡述生命周期。
Android中的四大組件Activity仇奶、Service比驻、BroadcastReceiver、ContentProvider狈茉。這些組件可以構(gòu)成一個(gè)完整的Application。四大組件都是有自己的生命周期的蹭秋,以Activity為例感凤,Activity可以認(rèn)為是一個(gè)小型App粒督,提供了onCreate()禽翼、onStart()闰挡、onResume()长酗、onPause()、onStop()夺脾、onDestroy()這些生命周期方法咧叭,包括后來(lái)的Fragment也遵循這一原則提供生命周期方法的回調(diào)菲茬。
我們自己開(kāi)發(fā)過(guò)程中的組件也借鑒同樣的思想婉弹,即每一個(gè)組件必須有自己的生命周期方法,每一個(gè)業(yè)務(wù)組件能夠像一個(gè)App一樣獨(dú)立運(yùn)行起來(lái)氯哮。
3. 組件間通信
Android中組件間通信是通過(guò)Intent實(shí)現(xiàn)蛙粘。
組件間通信包括兩個(gè)場(chǎng)景:(1)打開(kāi)組件的某個(gè)頁(yè)面(2)調(diào)用組件某個(gè)類(lèi)的某個(gè)方法。組件A表示調(diào)用著出牧,組件B表示被調(diào)用者舔痕,下面一一闡述伯复。
(1) 打開(kāi)一個(gè)頁(yè)面
打開(kāi)一個(gè)頁(yè)面啸如,通常指的是組件A要調(diào)起組件B的某個(gè)Activity
或Fragment
,這種情況往往采取的做法是URL Schema方式實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)想暗,格式為schema://host/action?param1=value1¶m2=value2
说莫。關(guān)于schema映射表維護(hù)以及schema解析和路由都是App Framework中的Framework來(lái)維護(hù)寞焙,需要上面提到的Router或Mediator這么一個(gè)角色捣郊。其中schema映射表可以做成后臺(tái)配置文件形式模她。也可以代碼維護(hù),不過(guò)組件需要預(yù)先注冊(cè)侈净。
以上說(shuō)的對(duì)于傳遞基本參數(shù)是沒(méi)啥問(wèn)題的畜侦。對(duì)于Serializable
或Parcel
對(duì)象傳遞也沒(méi)啥問(wèn)題,轉(zhuǎn)成JSON String就可以了澎语。而且通常也不會(huì)出現(xiàn)調(diào)起一個(gè)Activity
的時(shí)候擅羞,需要傳遞一個(gè)非序列化對(duì)象减俏,如ImageView過(guò)去的情況,真要處理ImageView
的話很多公司直接把圖片處理做成一個(gè)基礎(chǔ)功能組件奏夫,業(yè)務(wù)組件是可以顯式調(diào)用的酗昼。因此大部分公司組件間通信采用的是這種方式麻削。
然而事實(shí)上只考慮這種情況是不全面的碟婆,我們要從更高的層面來(lái)考慮問(wèn)題惕稻。
(2) 調(diào)用某個(gè)類(lèi)的某個(gè)方法
假設(shè)組件A調(diào)用組件B的某個(gè)類(lèi)的某個(gè)方法俺祠。由兩種方案可以達(dá)到目的蜘渣。
第一種蔫缸,在Mediator中定義組件B的interface
接口拾碌,組件B依賴Mediator
并實(shí)現(xiàn)對(duì)應(yīng)的interface接口方法校翔。然后當(dāng)組件A調(diào)用組件B的某個(gè)方法時(shí)灾前,組件A依賴Mediator去調(diào)用即可。貌似蘑菇街的protocol-class方案就是這么搞的饲嗽。
第二種奈嘿,Mediator中不定義任何組件的interface接口指么,直接通過(guò)反射機(jī)制(OC中的runtime)晚唇,將參數(shù)等穿進(jìn)去盗似,實(shí)現(xiàn)反射調(diào)用赫舒。這樣的話組件B是不需要依賴Mediator的。不過(guò)建議是Mediator對(duì)于不同組件的反射調(diào)用能提供一組映射關(guān)系心赶,而不是寫(xiě)到一起缨叫,這樣會(huì)導(dǎo)致Mediator太大太雜。這個(gè)思路就是casa大神說(shuō)的Category方案荔燎。
上面介紹的反射方式可以傳任何類(lèi)型的參數(shù)耻姥,嗯。
備注:Java中的interface相當(dāng)于OC中的protocol有咨。
(3) 小結(jié)
上面兩條其實(shí)是從兩種情況來(lái)考慮的琐簇,然而既然是架構(gòu),我們還是不希望出現(xiàn)座享,if else這種低級(jí)思考問(wèn)題的方式婉商。最好是能抽象出一個(gè)統(tǒng)一的方案。好征讲,根據(jù)上面我們是能發(fā)現(xiàn)(2)能解決(1)的問(wèn)題据某,而(1)不能解決(2)的問(wèn)題,即(1)是(2)的子集诗箍,因此從技術(shù)咖層面來(lái)講挽唉,最終得出的結(jié)論就是采用反射機(jī)制實(shí)現(xiàn)組件間通信這種方案比使用URL Schema這種方案更全面的埂材。
總結(jié)
1.理清依賴關(guān)系,要有抽象思維
2.才疏學(xué)淺裤唠,有理解不到位的地方航瞭,還請(qǐng)多多指教
3.疑問(wèn):casa大神的去core化以及去model化還是不太能夠理解长窄,需要繼續(xù)學(xué)習(xí)