從0寫一個ARouter


? ? ? ? 最近項目中越來越多使用組件化,所以記錄一下由此產生的最基本的一個問題:路由。

? ? ? ? ?安卓頁面間的跳轉想必是每一個學習安卓之人最先接觸的形病,最基本的方式就是直接調用startActivity方法紧阔。這種方法在以前整個工程都是單模塊的時候沒啥大問題,簡單也沒有必要去重新寫新的方法烤黍。但是隨著目前安卓開發(fā)趨向于模塊化組件化知市,如果想用這種方式實現(xiàn)組件間的跳轉,勢必會造成各個組件相互依賴速蕊,造成高耦合度嫂丙,這就違背了組件化非常重要的一個目的:解耦。這樣下來組件就只能適用于當前工程规哲,隨著項目頁面越來越多跟啤,本來作為組件的那部分卻移入了越來越多項目中的依賴,這時如果另一個工程想移入這個組件唉锌,估計開發(fā)人員要炸了隅肥,因為每次移入組件,都會有一堆報紅袄简,因為這個組件還有很大一部分對原來工程里的邏輯腥放。


? ? ? ? 解決思路肯定是解耦,首先想到利用利用scheme進行跳轉痘番,統(tǒng)一一個Activity,內部根據(jù)Uri獲取到domain,再進行統(tǒng)一判斷進行跳轉捉片,但是這樣不夠通用,每個activity都得配置一個判斷汞舱,換一個工程我們又得重新配置一遍伍纫,所以不夠完美。這樣行不通那利用反射機制呢昂芜?每個跳轉都得配置包名跟類名莹规,這個組件換個工程我們得把所有類名更換一遍,還不如上一個方法泌神。良漱。舞虱。。

? ? ? ? 我們想要的是不用每個activity都配置一遍跳轉的邏輯母市,只需要根據(jù)一個參數(shù)就能自動給我們配置好跳轉矾兜,這樣耦合性相當?shù)土恕D且陨线@些都行不通的話患久,有沒有現(xiàn)成的解決方案呢椅寺?

? ? ? ? 答案是當然有,阿里給我們提供了一個ARouter框架蒋失,耦合性低返帕,適合多模塊,支持攔截跟定制篙挽,路由也只需提供一個注解荆萤,無需自定義邏輯,完美解決了上述問題铣卡。使用起來也非常簡單链韭,就不做記錄了儒拂,搜一下去github上阿里寫了詳細的使用說明跟api用法。這里我們需要了解的是雾家,ARouter是如何提供了一套簡單的實現(xiàn)站宗,解決了上述問題,本人借鑒了部分源碼鉴腻,將基礎邏輯剝離了出來,整理成了個簡單的路由框架。

? ? ? ? 首先要想了解ARouter原理量淌,你需要先熟悉以下幾個知識基礎:1.注解跟注解處理器,2.Java apt技術嫌褪,3.JavaPoet動態(tài)依賴注入框架(這個比較重要呀枢,其他幾個帶注解的框架如EventBus,ButterKnife的基本原理也是這個框架)笼痛。這些就不做介紹了裙秋,不然又是個長篇大論。

我們根據(jù)使用ARouter步驟的順序開始整理思路缨伊。

首先跟ARouter一樣摘刑,先創(chuàng)建三個模塊,兩個java library跟一個android library:


路由框架模塊

分別是注解模塊刻坊,api模塊跟注解處理器模塊枷恕。

一:注解

先從注解模塊開始,我們先定義注冊路由地址的注解:


自定義注解


這里設置成對類注解谭胚,并設置成編譯時注解徐块,比較簡單未玻。

一:注解處理器

定義完注解我們需要處理注解處理器。先添加好依賴胡控,引入注解模塊扳剿,javapoet跟谷歌的auto service主動注冊處理器框架:


定義注解處理器RouterProcessor:


在上面添加自動注冊的注解,接下來需要實現(xiàn)注解處理器的幾個方法:


獲取內部工具類昼激,后面會用到


限定該注解處理器處理的注解舞终,這里指定為Router


這個方法最重要,在指定注解被使用后開始執(zhí)行


這里process方法中核心代碼集中在creatJavaCode中癣猾,該方法的作用是獲取注解信息生成java文件敛劝,生成類添加了方法,配置了包名跟實現(xiàn)的接口纷宇,我們看下代碼:





這里根據(jù)拿到的注解外部類的信息編譯時自動生成代碼夸盟,代碼的作用是將注解的外部類的路由信息跟路徑保存在一個map中。

我們看看生成的代碼像捶,跟我們構建代碼部分設置的一樣上陕,存儲的類實現(xiàn)了IRouterZ接口(到后面就知道為什么要專門實現(xiàn)一個接口而不只是添加方法了):


這樣一來最核心的路由信息存儲部分就完成了,它為我們省去了每個activity配置跳轉信息的操作拓春,不得不感慨javapoet這個功能是真的強大释簿。。硼莽。

三.讀取

接下來跳轉頁面我們就根據(jù)存下來的路由map進行跳轉庶溶,那么問題來了,編譯完之后我們如何從動態(tài)生成的代碼中獲取到路由信息呢懂鸵?

ARouter的思路是在初始化的時候就從生成的所有dex中去尋找實現(xiàn)了IRouterZ的類偏螺,這部分類即是動態(tài)構建代碼時生成的,然后傳一個相同的map進去依次執(zhí)行所有的onLoad方法匆光,這樣所有的路由信息就全部都保存到了我們自己創(chuàng)建的map中去套像,思路有了我們看看具體代碼:

既然是在初始化時候實現(xiàn)那肯定是Init方法作為入口:


init方法沒啥信息,我們看LogisticsCenter.init(context)里面執(zhí)行了什么:


再順勢跳到registerComm里面:


可以看出终息,這個方法從生成代碼時候配置的包名里面遍歷所有的class夺巩,找到實現(xiàn)了IRouterZ的類,最后執(zhí)行onLoad方法周崭,將路由信息存入Warehouse.routeMap中去柳譬,Warehouse.routeMap是個存放path跟路由信息的map:


三.路由跳轉

好了,最關鍵的配置休傍,存儲跟讀取都實現(xiàn)了征绎,最后一步的跳轉其實相對來說就很簡單了,因為在存儲的時候我們獲取到注解的外部類,比如activity人柿,fragment,獲取到了這些類其實最后就用最基本的startActivity就行了柴墩,當然,路由信息的結構在寫框架時你可以自己定義凫岖,所以跳轉前判斷邏輯也可能不盡相同江咳,這里我們還是參照ARouter寫,以activity為例:

首先activity中調用:


我們依次看這幾個方法,先看build:


可以看出build方法實際上是根據(jù)地址new了一個PostCard對象哥放,PostCard繼承了路由信息所在的類歼指,因此在這里它當做路由信息來用。

bundle方法實際上就是個set方法甥雕,將Bundle數(shù)據(jù)傳給postcard對象踩身。

最后關鍵的navigation方法肯定是跳轉了,我們看下怎么實現(xiàn)的:


跳到ZRouter的navigation方法中去:


因為最開始Postcard只有path被賦值了社露,單單靠這個無法完成跳轉挟阻,那么一直低調不被注意的Warehouse.routeMap終于派上用場了,這個我們把它稱之為路由表峭弟,在LogisticsCenter.complete(postcard);方法中附鸽,我們根據(jù)路由表完善了Postcard的各個參數(shù),我們看看:


setDestination設置了目標類瞒瘸,setRouteType設置了跳轉的類型坷备,這里是activity,因此根據(jù)上面代碼執(zhí)行的是startActivity(postcard)方法情臭,再看這個方法:


這部分就很簡單了省撑,設置啟動模式,設置intent傳參谎柄,最后在主線程運行startActivity完成跳轉丁侄。

由此惯雳,ARouter的基本功能也就實現(xiàn)了朝巫,看到最后可以總結出,歸根結底還是運用的startActivity石景,只不過判斷信息都巧妙的存放在了路由表里而已劈猿。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市潮孽,隨后出現(xiàn)的幾起案子揪荣,更是在濱河造成了極大的恐慌,老刑警劉巖往史,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仗颈,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機挨决,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門请祖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脖祈,你說我怎么就攤上這事肆捕。” “怎么了盖高?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵慎陵,是天一觀的道長。 經(jīng)常有香客問我喻奥,道長席纽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任撞蚕,我火速辦了婚禮胆筒,結果婚禮上,老公的妹妹穿的比我還像新娘诈豌。我一直安慰自己仆救,他們只是感情好,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布矫渔。 她就那樣靜靜地躺著彤蔽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庙洼。 梳的紋絲不亂的頭發(fā)上顿痪,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音油够,去河邊找鬼蚁袭。 笑死,一個胖子當著我的面吹牛石咬,可吹牛的內容都是我干的揩悄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼鬼悠,長吁一口氣:“原來是場噩夢啊……” “哼删性!你這毒婦竟也來了?” 一聲冷哼從身側響起焕窝,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹬挺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后它掂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巴帮,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了榕茧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片发乔。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖雪猪,靈堂內的尸體忽然破棺而出栏尚,到底是詐尸還是另有隱情,我是刑警寧澤只恨,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布译仗,位于F島的核電站,受9級特大地震影響官觅,放射性物質發(fā)生泄漏纵菌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一休涤、第九天 我趴在偏房一處隱蔽的房頂上張望咱圆。 院中可真熱鬧,春花似錦功氨、人聲如沸序苏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忱详。三九已至,卻和暖如春跺涤,著一層夾襖步出監(jiān)牢的瞬間匈睁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工桶错, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留航唆,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓院刁,卻偏偏與公主長得像糯钙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子黎比,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內容

  • ARouter是什么 ARouter是阿里巴巴開源的Android平臺中對頁面超营、服務提供路由功能的中間件,提倡的是...
    雪寶Wu閱讀 6,940評論 0 64
  • ARouter ARouter 是阿里云出品的Android中間件阅虫,負責處理盅跳轉頁面時的邏輯,簡化和優(yōu)化之前跳轉...
    常強兒閱讀 8,861評論 1 1
  • Arouter框架適合項目比較大不跟,模塊多的時候颓帝,可以實現(xiàn)解耦,不需要知道跳轉的是哪個activity,只需要知道配...
    破曉11閱讀 3,470評論 0 2
  • 手機響了购城,我接通電話:“喂——” “喂吕座。”是父親幽遠的聲音瘪板。 “爸爸吴趴。”我正要問他有什么事侮攀,電話卻斷了锣枝。可能是父親...
    木頭奶奶閱讀 1,687評論 102 99
  • 午后兰英,山路蜿蜒撇叁。紫花地丁躲在路邊草叢里,綿延成片畦贸。 光陨闹,一定是最容易被感染的物質。 你看薄坏,一開始趋厉,只有太陽發(fā)光,接...
    三生萬物Sun閱讀 653評論 11 14