Android 使用阿里ARouter頁面跳轉淺析


在工作的項目中使用到了阿里的開源工具Arouter作為頁面跳轉路由,這里記錄一下自己對于該框架使用一次跳轉的研究。

首先附上github鏈接GitHub - alibaba/ARouter: An android router middleware that help app navigating to activities and custom services.,對于Arouter的適用性、優(yōu)點和用法可以自行了解菱蔬。

在項目中加入了Arouter跳轉的代碼后,運行項目史侣,首先你會發(fā)現(xiàn)一些清單文件拴泌,位置在/build/generated/source/apt/release/com/alibaba/android/arouter/routes/下:


這里的幾個類分別實現(xiàn)了不同的接口,IRouteGroup惊橱、IInterceptorGroup蚪腐、IProviderGroup、IRouteRoot,這里我們以頁面的跳轉分析為主税朴,點開IRouteRoot削茁、IRouteGroup的實現(xiàn)類,你會發(fā)現(xiàn)它們都在loadInto方法對傳入的容器填充了一些數(shù)據(jù)掉房,在IRouteRoot的實現(xiàn)類中傳了IRouteGroup實現(xiàn)類的類名,在IRouteGroup實現(xiàn)類中傳入了一個封裝的RouteMeta的對象:


仔細一看每個RouteMeta的參數(shù)是不是很熟悉慰丛?里面出現(xiàn)了你已配置路徑的頁面名以及注解@Route中設置的path值:


其實在開發(fā)者配置完成后卓囚,ARouter會生成這些清單文件,在調用初始化方法init時會去加載這些清單文件诅病,將配置的頁面緩存起來哪亿,同時你也已經發(fā)現(xiàn)在loadinfo方法中體現(xiàn)的調用關系是存在root、group這些概念的贤笆。

如果你已經了解過Arouter,一定知道Arouter的一個特點:

映射關系按組分類蝇棉、多級管理,按需初始化

在這里按組分類芥永、多級管理其實已經體現(xiàn)出來了篡殷。

看完了清單文件,我們從Arouter的初始化開始入手:

ARouter.init(application);

往下查看埋涧,我們發(fā)現(xiàn)其實是調用了

_ARouter.init(application)

最終加載清單文件是LogisticsCenter.init方法中實現(xiàn)板辽,關鍵代碼如下:


首先我們按照正常的rlease版本的流程,進入else的代碼塊棘催,這里發(fā)現(xiàn)routerMap是從數(shù)據(jù)庫里面拿出來的劲弦,接來下對routerMap的內容className做循環(huán)判斷,這里className的三個判斷條件其實分別是:


ROUTE_ROOT_PAKCAGE +DOT +SDK_NAME +SEPARATOR +SUFFIX_ROOT:


com.alibaba.android.arouter.routes.ARouter$$Root


ROUTE_ROOT_PAKCAGE +DOT +SDK_NAME +SEPARATOR +SUFFIX_INTERCEPTORS:


com.alibaba.android.arouter.routes.ARouter$$Interceptors


ROUTE_ROOT_PAKCAGE+DOT +SDK_NAME +SEPARATOR +SUFFIX_PROVIDERS:


com.alibaba.android.arouter.routes.ARouter$$Providers


找到了清單文件類之后傳入了Warehouse類中的成員變量并表用loadInfo方法醇坝,到此初始化已經結束邑跪,再進入Warehouse中瞧一瞧:


可見對于頁面來說,清單的配置最后被緩存到了WareHouse這個類,頁面只緩存到了節(jié)點不做下級的加載画畅,這也就是之前說的按需加載砸琅,這里只存到了類名并沒有把節(jié)點全部緩存下來。

在發(fā)起一個頁面跳轉的請求的時夜赵,所有的請求都被封裝成了一個Postcard對象明棍,我們先來看看這個對象如何生成的,最開始Arouter調用的是build方法:


_Arouter的build方法返回了一個新的Postcar對象:


看看這個PathReplaceService是如何生成的寇僧,順著navigation方法往下看摊腋,最后在_Arouter的navigation的方法中返回

這里在buildProvider中會對IRouterProvider的緩存中查詢是否注冊了對應的provider,僅僅只做頁面跳轉這里可以不用注冊嘁傀,那么整個方法會拋出異常兴蒸,在catch塊中返回null。那么在build中則會進入build(path, extractGroup(path))方法:


在這個方法中细办,由上面的分析可知這里的pService為空橙凳,所以最簡單的情況就是返回一個新的由path和group決定的Postcard。

再進行跳轉時笑撞,將會調用Postcard的navigation方法岛啸,最終是將自己傳入了_Arouter的navigation方法中:

protected Object navigation(final Context context,final Postcard postcard,final int requestCode,final NavigationCallback callback)?

在該方法中首先調用了LogisticsCenter.completion(postcard),這方法比較長茴肥,一段一段來看坚踩,其實這是個注冊Postcard的方法:


首先從Root容器中去查找有沒有對應的內容,從我們之前的加載過程中看是肯定找不到的瓤狐,那么第二步則從Group中去找瞬铸,找到了之后則把頁面的內容加載到routes容器中,這里是通過之前init緩存的類名找到對應的Group础锐,然后調用Group的loadInfo方法緩存具體的每個節(jié)點嗓节,也就是到了要使用的時候再加載具體的節(jié)點,loadInfo是最開始清單文件中IRouterGroup實現(xiàn)類的方法皆警,具體的填充過程看一下就知道了拦宣,再重新reload。



else代碼塊里對于已經緩存的內容信姓,則把相應的屬性填入Postcard中恢着,也就是把routeMeta轉化為Postcard

在最后會對routeMeta的類型做判斷,在清單文件類中财破,new reoutMeta時會將頁面的類型傳入掰派,所以這里是可以判斷的。

在LogisticsCenter.completion(postcard)完成之后接著判斷是否走的是綠色通道greenChanel(跳過所有的攔截器):


我們先看跳過攔截器的else內的代碼塊左痢,接著調用_navigation()方法:


可見跳轉的地方就在這里啦靡羡,在回到之前是否走綠色通道的邏輯系洛,如果是不跳過攔截器,則會調用interceptorService.doInterceptions(postcard,new InterceptorCallback())略步,這里interceptorService是一個接口描扯,我們找到它的實現(xiàn)類com.alibaba.android.arouter.core.InterceptorServiceImpl瞧一瞧doInterceptions()方法:


著這個方法中首先會判斷是否注冊了攔截器被緩存進來,攔截器的緩存也是在init的操作中已經做過的趟薄,如果有的話則開啟一個線程绽诚,這里攔截器相關都是異步的,因為攔截器的操作可能非常耗時杭煎,其中_excute()方法是攔截器操作的地方恩够,接著看下去:


根據(jù)index依次取出攔截器,并調用process()方法羡铲,而當我們定義一個攔截器的時候蜂桶,最重要的便是重寫IInterceptor的process()方法,那么到這里攔截器是如何運作已經一目了然了:

還有一個問題也切,攔截器是有優(yōu)先級的扑媚,這里又是怎么按照優(yōu)先級攔截,如果斷開后續(xù)攔截又是怎么斷開的雷恃,首先我們看在代碼中定義的攔截器疆股,這里使用了注解去定義該攔截器的優(yōu)先級:


在清單文件中加載攔截器時會將該優(yōu)先級作為key填充到容器中:

在_excute()方法中從緩存中調用攔截器是從index=0作為索引開始的,如果繼續(xù)攔截則在continue中使index+1并遞歸倒槐,這樣就實現(xiàn)了按照優(yōu)先級攔截:


在清單文件中攔截器的加載說明Warehouse中interceptorsIndex存儲的內容以攔截器的優(yōu)先級作為key押桃,攔截器的類名作為value,并且interceptorsIndex是一個TreeMap,而攔截器具體的類在使用的時候是從interceptors中加載過來的导犹,這其實是在InterceptorServiceImpl中完成的,在_Arouter完成init之后馬上會調用一次afterInit():

interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();

到最后會走到LogisticsCenter.completion()方法羡忘,在之前我們發(fā)現(xiàn)這個方法最后會對routMeta的類型做判斷:


當判斷為IProvider接口類型時會調用init的方法谎痢,回到InterceptorServiceImpl你會發(fā)現(xiàn)這個類實現(xiàn)了InterceptorService接口,而InterceptorService又繼承自IProvider接口卷雕,那么很明顯了节猿,看看InterceptorServiceImpl的init()方法:


Warehouse.interceptors的填充就在這里了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末漫雕,一起剝皮案震驚了整個濱河市滨嘱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浸间,老刑警劉巖太雨,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異魁蒜,居然都是意外死亡囊扳,警方通過查閱死者的電腦和手機吩翻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锥咸,“玉大人狭瞎,你說我怎么就攤上這事〔瑁” “怎么了熊锭?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雪侥。 經常有香客問我碗殷,道長,這世上最難降的妖魔是什么校镐? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任亿扁,我火速辦了婚禮,結果婚禮上鸟廓,老公的妹妹穿的比我還像新娘从祝。我一直安慰自己,他們只是感情好引谜,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布牍陌。 她就那樣靜靜地躺著,像睡著了一般员咽。 火紅的嫁衣襯著肌膚如雪毒涧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天贝室,我揣著相機與錄音契讲,去河邊找鬼。 笑死滑频,一個胖子當著我的面吹牛捡偏,可吹牛的內容都是我干的。 我是一名探鬼主播峡迷,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼银伟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绘搞?” 一聲冷哼從身側響起彤避,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夯辖,沒想到半個月后琉预,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡蒿褂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年模孩,在試婚紗的時候發(fā)現(xiàn)自己被綠了尖阔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡榨咐,死狀恐怖介却,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情块茁,我是刑警寧澤齿坷,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站数焊,受9級特大地震影響永淌,放射性物質發(fā)生泄漏。R本人自食惡果不足惜佩耳,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一遂蛀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧干厚,春花似錦李滴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挂捅,卻和暖如春芹助,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闲先。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工状土, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伺糠。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓蒙谓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親退盯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容

  • 轉至元數(shù)據(jù)結尾創(chuàng)建: 董瀟偉泻肯,最新修改于: 十二月 23, 2016 轉至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評論 0 9
  • ARouter源碼解讀 以前看優(yōu)秀的開源項目渊迁,看到了頁面路由框架ARouter,心想頁面路由是個啥東東灶挟,于是乎網上...
    陸元偉閱讀 522評論 0 1
  • 1.要做一個盡可能流暢的ListView琉朽,你平時在工作中如何進行優(yōu)化的? ①Item布局稚铣,層級越少越好箱叁,使用hie...
    fozero閱讀 720評論 0 0
  • 標簽 如果要配置的標簽墅垮,那么必須要先配置標簽,代表的包的概念耕漱。 包含的屬性 name包的名稱算色,要求是唯一的,管理a...
    偷偷得路過閱讀 1,343評論 0 0
  • 周日下午收到了前幾日下單的《按自己的意愿過一生》螟够,兩小時翻完了這本220頁的小書灾梦。縱觀整本書妓笙,最喜歡的要數(shù)第一章-...
    水桶君閱讀 340評論 1 3