有貨Android組件化下的路由實踐

背景

隨著有貨App的業(yè)務(wù)不斷迭代,功能不斷累積,原有的項目架構(gòu)逐漸出現(xiàn)了以下問題:業(yè)務(wù)模塊代碼邊界不清晰驶臊,耦合過重;業(yè)務(wù)代碼與通用代碼的耦合導(dǎo)致很多重復(fù)代碼叼丑;基礎(chǔ)組件庫的不完善導(dǎo)致了一些三方庫的重復(fù)关翎。鑒于此,組件化勢在必行鸠信,一個簡易的架構(gòu)分層圖如下:

單向依賴纵寝,業(yè)務(wù)組件相互之間無依賴關(guān)系,那業(yè)務(wù)組件之間的頁面跳轉(zhuǎn)該如何解決呢症副?

路由

現(xiàn)在比較通用的一個解決辦法是采用路由店雅,現(xiàn)在社區(qū)有很多開源路由框架,比如ARouter贞铣,DeepLinkDispatch闹啦,ActivityRouterLiteRouter等辕坝,再結(jié)合有貨現(xiàn)有的業(yè)務(wù)跟組件化架構(gòu)窍奋,基于以下幾點實現(xiàn)一個路由方案:

  1. 注解配置,通過APT在編譯時去生成各個組件的路由表

  2. AspectJ去匯總各個組件的路由表,同樣通過APT生成輔助代碼實現(xiàn)

  3. 路由調(diào)用支持原本Bundle支持的各種數(shù)據(jù)類型琳袄,各種Activity跳轉(zhuǎn)的Flags江场,跳轉(zhuǎn)動畫以及支持startActivityForResult

  4. 支持?jǐn)r截器,特別是先跳轉(zhuǎn)登錄再跳轉(zhuǎn)請求的頁面這種異步的場景窖逗,可以通過RxJava的Subject實現(xiàn)

  5. Activity的參數(shù)自動注入址否,類似ButterKnife,這個優(yōu)先級不高

  6. 路由后的結(jié)果回調(diào)

  7. 兼容原本App中的老跳轉(zhuǎn)規(guī)則碎紊,可以將原來的流程對接到新的路由sdk

簡單用一個流程圖表示一下佑附,下面會具體講:

實踐

對于上面說的幾點,我從路由使用的角度來詳細(xì)闡述一下仗考。

  1. 首先整個路由sdk有三部分組成

· router是一些代碼中用到的API

· router-annotation定義了一些需要用到的注解

· router-processor定義了注解處理器

· 初始化

在Application的onCreate()里初始化路由sdk音同,所做的事情很簡單,只是初始化一個List秃嗜,這個List負(fù)責(zé)匯總各個組件模塊中的路由权均。

  1. 路由定義

· 這個注解會在編譯時由注解處理器來解析

· 此注解支持配置多個url

· url的格式:scheme://host/path/{paramKey},url正則匹配锅锨,為了不使url的解析過于復(fù)雜叽赊,這里的param匹配只會解析成String類型,對于其余的類型則可通過Router API手動添加

· url匹配舉例:yoho://detail/88

除了Router這個注解還需要一個RouterModule注解:

· 這個注解同樣在編譯時由注解處理器來解析橡类,注解一個空類即可蛇尚,它會生成一個類DetailModuleRouter,這個類生成在當(dāng)前組件的包名下顾画,用來匯總該組件下所有的Router注解并放入一個List中用于匹配

· 除此之外取劫,注解處理器還需要在DetailModuleRouter中插入一段AspectJ調(diào)用代碼,用于匯總各個組件模塊路由:

簡單解釋一下研侣,就是將該組件的路由module類加到一個匯總所有路由module類的List中谱邪,這個List就是上面第二步所說的初始化的List,加入的地方與時機便是由AspectJ來決定庶诡,這段AspectJ注解的意思就是切入路由sdk的初始化方法惦银,在調(diào)用該方法后的代碼中去執(zhí)行該組件的路由匯總工作,其他組件同理末誓。這樣做主要是因為組件化后各個業(yè)務(wù)組件編寫代碼期間無依賴關(guān)系扯俱,只有編譯運行后才可見([參照得到的組件化方案]),也就不能強引用各個組件的路由module類喇澡,而AspectJ則是在編譯期間AOP正好可以應(yīng)對這個情況迅栅,由于項目中之前做其他功能已經(jīng)引入了AspectJ,所以對于我們來說不是很重的選擇晴玖。

· 我們看下AspectJ后的字節(jié)碼:

  1. 編譯期所做的事情基本理完读存,下面就是正式調(diào)用Router相關(guān)的API为流,一個例子如下:



    RouterCall代表了一次路由操作,用Builder模式去構(gòu)造让簿,有很多putXxx方法敬察,可以去添加Bundle支持的各種數(shù)據(jù)類型,Activity相關(guān)的Flags(如Intent.FLAG_ACTIVITY_NEW_TASK)尔当,Activity直接跳轉(zhuǎn)的動畫等莲祸,這些數(shù)據(jù)都封裝在RouterMap這個類中,然后支持添加攔截器和routerCallback椭迎,這兒的攔截器是同步的虫给,異步的后面會說,route有一個重載的帶requestCode的方法侠碧,如果帶入一個大于0的值,則會去調(diào)用startActivityForResult缠黍。攔截器調(diào)用鏈參考了okHttp的實現(xiàn)弄兜,真正的路由跳轉(zhuǎn)操作也當(dāng)成一個攔截器,放到所有攔截器的最后瓷式。下面是這個過程的一個簡單時序圖:

  1. 異步攔截器

2· 并沒有放到路由sdk中替饿,因為跟業(yè)務(wù)有一些耦合

3· 我這里用RxJava的PublishSubject來實現(xiàn),Subject屬于Hot Observable贸典,有點類似EventBus视卢,但是可以當(dāng)成一個專用的EventBus

4· 一個簡單例子如下:


如果需要登錄則先路由到登錄,登錄成功后發(fā)射一下:sUserPublishSubject.onNext(sUser)則會跳轉(zhuǎn)到原先的路由頁面廊驼,要注意及時的dispose据过,否則界面會亂跳。

總結(jié)

上面列出了路由實踐中重要的一些點妒挎,還有些未實現(xiàn)比如支持方法調(diào)用绳锅,安全考慮,會逐步完善酝掩。為方便開發(fā)鳞芙,形成一份路由url映射的文檔很有必要,這個也可以在編譯時去生成期虾,可以參考DeepLinkDispatch原朝,不再贅述。

參考文獻(xiàn)

感謝社區(qū)優(yōu)秀的路由庫和相關(guān)文章:

· http://www.reibang.com/p/8a3eeeaf01e8

·https://github.com/airbnb/DeepLinkDispatch

· https://github.com/alibaba/ARouter

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镶苞,一起剝皮案震驚了整個濱河市喳坠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宾尚,老刑警劉巖丙笋,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谢澈,死亡現(xiàn)場離奇詭異,居然都是意外死亡御板,警方通過查閱死者的電腦和手機锥忿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怠肋,“玉大人敬鬓,你說我怎么就攤上這事◇细鳎” “怎么了钉答?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杈抢。 經(jīng)常有香客問我数尿,道長,這世上最難降的妖魔是什么惶楼? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任右蹦,我火速辦了婚禮,結(jié)果婚禮上歼捐,老公的妹妹穿的比我還像新娘何陆。我一直安慰自己,他們只是感情好豹储,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布贷盲。 她就那樣靜靜地躺著,像睡著了一般剥扣。 火紅的嫁衣襯著肌膚如雪巩剖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天朦乏,我揣著相機與錄音球及,去河邊找鬼。 笑死呻疹,一個胖子當(dāng)著我的面吹牛吃引,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刽锤,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼镊尺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了并思?” 一聲冷哼從身側(cè)響起庐氮,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宋彼,沒想到半個月后弄砍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仙畦,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年音婶,在試婚紗的時候發(fā)現(xiàn)自己被綠了慨畸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡衣式,死狀恐怖寸士,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碴卧,我是刑警寧澤弱卡,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站住册,受9級特大地震影響婶博,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荧飞,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一凡蜻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垢箕,春花似錦、人聲如沸兑巾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒋歌。三九已至帅掘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間堂油,已是汗流浹背修档。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留府框,地道東北人吱窝。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像迫靖,于是被迫代替她去往敵國和親院峡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355