探索Android路由框架-ARouter之基本使用(一)

? ?本文已獨家授權 郭霖 ( guolin_blog?) 公眾號發布!

????本文意在快速集成并掌握阿里Android技術團隊開源的一款路由框架。這款路由框架可以為我們的應用開發提供更好更豐富的跳轉方案。比如支持解析標準URL進行跳轉,并自動注入參數到目標頁面中;支持添加多個攔截器,自定義攔截順序(滿足攔截器設置的條件才允許跳轉,所以這一特性對于某些問題又提供了新的解決思路)。

????本文示例代碼基于ARouter框架最新1.3版本進行編寫。介于篇幅的原因將其分成兩篇,第一篇主要介紹該框架的配置以及基本使用;第二篇主要的內容是通過現象去研究路由框架的源碼。

? ? 如果對ARouter的使用已經爛熟于心,那么可以直接進入第二篇?ARouter源碼分析?

前言:

? ? 首先借用阿里云棲社區的一段話:我們所使用的原生路由方案一般是通過顯式intent和隱式intent兩種方式實現的(這里主要是指跳轉Activity or Fragment)。在顯式intent的情況下,因為會存在直接的類依賴的問題,導致耦合非常嚴重;而在隱式intent情況下,則會出現規則集中式管理,導致協作變得非常困難。一般而言配置規則都是在Manifest中的,這就導致了擴展性較差。除此之外,使用原生的路由方案會出現跳轉過程無法控制的問題,因為一旦使用了StartActivity()就無法插手其中任何環節了,只能交給系統管理,這就導致了在跳轉失敗的情況下無法降級,而是會直接拋出運營級的異常。這時候如果考慮使用自定義的路由組件就可以解決以上問題,比如通過URL索引就可以解決類依賴的問題;通過分布式管理頁面配置可以解決隱式intent中集中式管理Path的問題;自己實現整個路由過程也可以擁有良好的擴展性,還可以通過AOP的方式解決跳轉過程無法控制的問題,與此同時也能夠提供非常靈活的降級方式。

ARouter官方項目地址

添加依賴

添加依賴

javaCompileOptions {

annotationProcessorOptions {

arguments = [moduleName :project.getName() ]

} }

compile'com.alibaba:arouter-api:1.3.1'

annotationProcessor'com.alibaba:arouter-compiler:1.1.4'

初始化

官方建議我們在Application里面進行ARouter初始化,于是乎就有了以下代碼:


初始化

然后別忘記了在清單文件里面配置自定義的Application和我們的Activity。

項目依賴導入和初始化就已經完成了,下面就開始正式的功能使用以及簡單的封裝。

開始使用:

1)首先:在Activity/Fragment類上面寫上 Route path 注解。

? ? ? 注意:這里的路徑需要注意的是至少需要有兩級,/xx/xx

2)然后:在Activity/Fragment類里面進入Arouter 注入,也就是:ARouter.getInstance().inject(this);

3)接著:目標的Activity類上面需要聲明Route path 注解,以此對應(跳轉如果不對應路徑,框架會Toast說路徑不匹配)

上述說明的簡單使用如下圖:

簡單使用

理論上來說,如果只是進行簡單的跳轉頁面,

ARouter.getInstance().build(“目標界面對應的路徑”).navigation(); 就這樣一行代碼即可完成跳轉界面。

好了,看到這里我們就會發現,路徑的標簽如果多了就不是很好管理,(所以更好的選擇是寫一個類,在這個類里面統一管理和維護路徑標簽,不僅利于維護也方便后期拓展,看到路徑就一目了然,哇~這個路徑對應的是登錄界面,這個路徑對應的是詳情界面);其次,每個頁面的注入,也就是ARouter.getInstance().inject(this);這句代碼出現的幾率會寫的很多,(而且一般的常規邏輯是有注入就有解綁或者釋放資源)所以我們應該簡單封裝起來提高效率

簡單封裝

首先是路徑管理:

路徑統一管理

然后是注入封裝:

這里多提一嘴,優秀的第三方框架如果一般有注入或者綁定的API,那與之對應的一般就會有釋放或者解綁資源的API。(這樣做的本質是優化內存)其中, ARouter.getInstance().destroy( ) ; 這個API一目了然,就是釋放資源的API。下面就是開始注入和釋放資源的封裝:

注入封裝

筆者在Activity的基類里面通過生命周期進行了注入和解綁,但是項目運行后發現了一個問題,就是如果在onDestroy()里面調用了?ARouter.getInstance().destroy( ) ; 在進入目標Activity之后,然后按back鍵返回原界面的時候,APP會報錯崩潰,下面是崩潰日志:

????仔細一看,初始化有問題?在前面我們說到在自定義Application里面已經初始化了ARouter,且在清單文件里面配置了自定義的Application,但是依舊提示沒有初始化,這就納了個悶?然后想了想,可能是?ARouter.getInstance().destroy( );這行代碼的使用位置可能用錯了。然后既然是在Application里面進行的初始化,那么就可以將這行釋放資源的代碼,寫在Application生命周期的onTerminate( )里面,果不其然,項目運行后就沒什么問題了。當然,這是我自己的思路,有更好的意見和想法請在評論區指出,謝謝。

初始化

封裝完畢了路徑標識以及注入釋放等基本功能,我們回到ARouter的基本使用:

簡單頁面跳轉

如果只是簡單的頁面跳轉,一行代碼即可完成,如下圖

簡單跳轉 - 1

其中,build里面是頁面的標簽路徑,對應的就是目標Activity的這里,也就是類注釋標簽路徑要一致:

Ps:不要忘了在清單文件里面配置Activity。

帶參數的界面跳轉

????帶參數的跳轉是很常見的功能,Android可以通過Bundle去傳遞參數,如果使用ARouter框架,它傳遞參數通過以下去操作:

????ARouter傳遞對象的時候,首先該對象需要Parcelable或者Serializable序列化,可能Parcelable這個序列化大家覺得手寫起來比較麻煩,但是Android Studio已經有一些插件幫我們自動生成Parcelable序列化了(因為Android用Parcelable序列化優勢會更加明顯一些)

????字符串、char、int等基本數據類型當然都是可以傳遞的

????當然,它也可以直接傳Bundle、數組、列表等很多對象,傳遞類型如下圖

傳遞類型

攜帶參數的界面跳轉,簡單使用如下圖

跳轉傳遞參數

其中,第一個參數代表的是參數的key,第二個參數對應的是我們要傳遞的屬性值,也就是value

那么目標界面如何獲取傳遞過來的值?

這個時候,我們需要在目標界面,使用Autowired注解,

Autowired 注解

這樣就可以獲取到傳遞過來的值了

獲取屬性值

值得注意的是,只有當 @Autowired(name = "test"),也就是key標簽一致的情況下,才可以獲取到對象的值,如果不寫標簽名,結果會為null,

Autowired 注解

所以為了規避每一個可能會遇到的風險,建議在@Autowired里面 都寫上與之對應具體的key名。

界面跳轉動畫

直接調用withTransition,里面傳入兩個動畫即可(R.anim.xxx)

跳轉動畫

使用URI進行跳轉

ARouter框架也可以使用URI進行匹配跳轉,代碼也很少,只需匹配路徑一致即可完成跳轉:

URI - 匹配跳轉

Fragment跳轉

Fragment的跳轉也可以參照Activity跳轉,第一步依舊是先寫上類注釋,然后是強轉,代碼如下

Fragment跳轉

進階用法之攔截器:

????攔截器是ARouter這一款框架的亮點。說起攔截器這個概念,可能印象更加深刻的是OkHttp的攔截器,OkHttp的攔截器主要是用來攔截請求體(比如添加請求Cookie)和攔截響應體(判斷Token是否過期),在真正的請求和響應前做一些判斷和修改然后在去進行操作,大抵這就是攔截器的簡單概念。那么,ARouter框架的攔截器是怎么實現的?

????ARouter的攔截器,是通過實現?IInterceptor接口,重寫init()和process()方法去完成攔截器內部操作的。

????首先我們定義兩個攔截器:

攔截器 - 1
攔截器 - 2

????首先,定義ARouter攔截器必須要使用Interceptor類注解。注解里面的 priority(也就是紅色框) 這個是聲明攔截器的優先級、里面的屬性值是int類型。既然是定義優先級,我們這里定義2個攔截器來測試看看優先級是如何區分誰先誰后的?兩個攔截器寫完之后,運行下項目看下效果:

攔截器初始化先后順序

????結論 1:根據實驗得知,使用Interceptor類注解的priority數值越小,越先執行,優先級越高。(四大組件中的廣播,優先級的取值是 -1000到1000,數值越大優先級越高)

????那么,還有一種情況,如果兩個攔截器定義的優先級都是一樣的,那么誰的優先級會高?是根據類的字符串長度來判斷嘛還是別的條件來判斷的??

????首先,將上面的攔截器的優先級改成一樣(都改成1),項目編譯試試,結果發現項目就會直接報錯!

同優先級問題

????看下具體的錯誤原因:

相同優先級錯誤原因

????翻譯過來就是他們使用了相同的優先級,所以:

????結論 2:如果兩個攔截器的優先級一樣,項目編譯就會報錯。所以,不同攔截器定義的優先級屬性值不能相同

????我們到這兩個攔截器里面加一點篩選條件的代碼:

攔截器 - 3

????將這段代碼加進去之后,重新運行App,打印日志結果如下:

攔截器 - 執行流程

????為了方便看清運行的日志,我用三種顏色的箭頭去對應。首先是兩個攔截器的初始化,然后,調用了NavigationCallback這個回調函數里面的onFound(),然后執行了攔截器里面的process()方法;當攔截器的process()方法執行完畢以后,最終回調了NavigationCallback里面的onArrival()方法。攔截器的工作流程大抵就是這樣。那么,NavigationCallback這個又是什么?實際上,NavigationCallback這個簡單理解就是ARouter在路由跳轉的過程中,我們可以監聽路由的一個具體過程。它一共有四個方法:

NavigationCallback

那么,這個回調里面的 Postcard 又是什么意思?點進去源碼看看,類注釋寫的一目了然:

Postcard類注釋

紅色框翻譯過來的類注釋就是:一個包含路線圖的容器。

既然是路線圖的容器,那肯定有些API會獲取到相應的信息,

Group簡單使用

????通過Postcard可以獲取到路徑的組以及全路徑,那么,路徑的組(Group)又是什么?是這樣,一般來說,ARouter在編譯期框架掃描了所有的注冊頁面/字段/攔截器等,那么很明顯運行期不可能一股腦全部加載進來,這樣就太不和諧了。所以就使用分組來管理,我們的類標簽里面的注釋,對于group默認是 “ ”(空字符串)如下圖:

????在 Group簡單使用 這張圖上面,根據日志,打印了分組的信息,可以發現Group的值默認就是第一個 / ?/(兩個分隔符) 之間的內容。

????那么,我們也可以自定義分組,來進行界面跳轉,所以ARouter又提供了一種解決方案:

自定義分組 實現跳轉界面

如果使用自定義分組來跳轉界面,只需要在源代碼改動以下三個位置:

1:類注解新增 group,賦值我們自定義的組名,(依舊統一寫在一個類里面這樣便于管理)

自定義分組跳轉界面 - 1

2:在build方法里面(這是一個方法重載),添加我們的與之對應的組名

自定義分組跳轉 - 2

3:在被跳轉的Activity里面的類注釋,加上同樣的組名

自定義分組跳轉 - 3

通過上面三個步驟即可完成 自定義分組 來完成界面跳轉

自定義分組顯示結果

通過日志顯示,這里的組名已經被我們更改成自定義分組且成功完成了跳轉。

ARouter如何實現類似startActivityForResult()?

這種應用場景也是很常見的,那ARouter該如何實現?

第一步:為了方便看效果,我們在第一個Activity設置requestCode 為123,

onActivityResult

第二步:需要在跳轉的navigation方法(這是一個方法重載)里面的第二個參數,設置我們定義的requestCode,(通過匹配requestCode 來實現該功能)

第三步:在第二個界面的setResult方法里面,寫上對應的resultCode,這里就不展示Intent數據了

綜合上面三個步驟,項目編譯運行,跳轉到第二個界面然后返回上一個界面,日志成功打印:

ARouter路由框架的基本使用就介紹到這里,源碼分析請看第二篇。

探索Android路由框架-ARouter之深挖源碼

如果這篇文章對您有開發or學習上的些許幫助,希望各位看官留下寶貴的star,謝謝。

Ps:著作權歸作者所有,轉載請注明作者, 商業轉載請聯系作者獲得授權,非商業轉載請注明出處(開頭或結尾請添加轉載出處,添加原文url地址),文章請勿濫用、開源項目僅供學習交流、也希望大家尊重筆者的勞動成果,謝謝。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,844評論 2 372

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,615評論 25 708
  • 開發一款App,總會遇到各種各樣的需求和業務,這時候選擇一個簡單好用的輪子,就可以事半功倍 前言 上面一段代碼,在...
    WangDeFa閱讀 65,823評論 44 198
  • 今天去南站把去拉薩的車票退了,好在最后一天帶著身份證,沒有額外費用產生。 隨后去了國際婦幼保健院,還是很感恩在收費...
    愛思塔閱讀 216評論 1 0