天天看點

ARouter 在多 module 項目中實戰

本文已首發微信公衆号「code小生」,大家可以搜尋關注,專注安卓技術分享。

本文僅作案例示範,友善學習和掌握基礎知識,不進行源碼級别的探究。下面先明确一下能實作的功能和用到的技術點以及環境。

技術點:

多module工程,有baselib和主app以及多業務module

多module,實作某個module可獨立運作

多module之間跳轉,使用arouter架構

arouter攔截器使用

環境:

android studio4.1.2

語言:java

手機:三星a6s android10

安卓的項目結構發展越來越傾向于多子產品,而子產品間的跳轉如果使用原生方式(<code>intent跳轉</code>),那麼會随着項目的發展壯大,最終導緻錯綜複雜的<code>import xxx</code>,進而給維護帶來很大的麻煩,如下圖這樣:

ARouter 在多 module 項目中實戰
<code>黑色線條:</code> 表示依賴關系,有了依賴,就可以在目前子產品引用其他子產品的類,就可以使用<code>intent</code> 跳轉。&lt;br/&gt; <code>藍色線條:</code> 表示從app子產品要跳轉login,live,work子產品的某個頁面,那麼必須依賴對應子產品才可以引用到相關類,進而實作跳轉。&lt;br/&gt; <code>紅色線條:</code> 業務需要,從work子產品可以直接進入直播間,那麼work子產品就必須依賴live子產品;反之亦然。&lt;br/&gt; <code>綠色線條:</code> 當使用者沒有登入,或者登入狀态失效,亦或者賬号在别處登入了,那麼需要從目前子產品跳轉到login子產品,是以其他基礎子產品都要依賴login子產品。

這樣随着項目功能的拓展,帶來的問題就很明顯了。

而<code>arouter</code>的出現,就很好的解決了這個問題,官網位址:<code>https://github.com/alibaba/arouter/</code> ,其功能很強大,對于多子產品的項目,無論是否元件化,都很好的解決了互相依賴和跳轉帶來的維護成本。如下簡易圖:

ARouter 在多 module 項目中實戰
<code>黑色線條:</code> 表示依賴關系,這裡的依賴主要是解決資源共用問題,而不是跳轉。如果用不到baselib中的資源,那麼無需依賴。&lt;br/&gt; <code>其他虛線條:</code> 表示無需互相依賴,就可以實作頁面跳轉和通信,這就是路由的強大之處。&lt;br/&gt;

我這裡命名為<code>myarouter</code>,然後分别 new module:<code>baselib</code>、<code>circle</code>、<code>home</code> 選擇 android library 類型,編譯完成如下圖,則為正常狀态;

ARouter 在多 module 項目中實戰

win 系統通過快捷鍵 <code>ctrl+shift+alt+s</code> 調出 <code>project structure</code> 面闆,當然你也可以通過點選菜單欄的<code>file-&amp;gt;project structure</code> 來打開這個面闆。

ARouter 在多 module 項目中實戰

如圖選擇不同的子產品,添加依賴子產品即可,我這裡的依賴是這樣的:

app子產品依賴:<code>baselib</code>、<code>circle</code>、<code>home</code>

baselib子產品:不依賴任何功能子產品

circle子產品依賴:<code>baselib</code>

home子產品依賴:<code>baselib</code>

子產品說明

<code>baselib</code>:項目的公共基礎子產品,一般可以包括共用的工具類、公共資源、公共代碼片段、共用三方引用等等可以放在這裡,這樣做可以避免很多的重複代碼、提高代碼的可閱讀性和程式的易維護。

<code>app</code>:是整個項目的宿主子產品,也就是說該子產品的優先級是高于其他功能子產品的,因為程式的主入口是這裡。

其他子產品,都是按照業務功能來劃分,負責具體的業務。

打開<code>baselib</code>下的<code>build.gradle</code>檔案,在<code>dependencies</code>下添加如下代碼

接着在<code>baselib</code>下建立 <code>baseapplication</code> 類,完整代碼如下:

然後建立類<code>arouterpath</code>,該類的功能是提供統一的路由跳轉頁面路徑,也就是arouter中的path值;

依次在<code>app</code>、<code>circle</code>、<code>home</code>子產品,打開對應的<code>build.gradle</code>檔案

在<code>dependencies</code>下添加如下代碼

在<code>defaultconfig</code>下添加如下代碼

到這裡,其實路由的引用配置已經完成,但我們還沒有添加application,也很簡單了,在<code>app</code>子產品下,建立<code>appapplication</code>繼承自<code>baseapplication</code>,并将其添加到該子產品下的清單檔案中。

這裡不做實作是因為示範demo,用不到第三方的東西,實際開發中根據需求進行初始化即可。之是以繼承,是因為前面我們已經初始化了路由配置。

配置工作我們已經做完了,本文的主要目的就是測試頁面跳轉,當然跳轉就會包含是否攜帶參數、跳轉是否需要有傳回值、以及沒有依賴關系的子產品間是否可跳轉,下面進行分組測試:

tips:為了避免寫<code>findviewbyid()</code> ,我這裡使用了<code>viewbinding</code>,用法很簡單,一看就懂,這裡不做詳細說明。

子產品内的話,完全可以使用<code>intent</code>方式跳轉,但本文的主題是探究路由的跳轉用法,我這裡以<code>app</code>子產品内跳轉為例,建立了一個名為<code>myinfoactivity</code>的頁面,顯示預設值,通過在<code>mainactivity</code>攜帶參數跳轉指派來展示使用示例。

ARouter 在多 module 項目中實戰
如果你的配置都沒有錯,還是無法跳轉,那麼解除安裝app重新運作,就是ok的,因為路由位址<code>path</code>有映射,緩存下來了,雖然後面改了,但走的還是緩存。

傳參說明

arouter提供了多種方式傳遞參數,也支援原生的參數值類型,如下圖:

ARouter 在多 module 項目中實戰

這裡不示範全部方法的使用,隻要會了下面幾個常用的,其他都類似。

<code>with(bundle bundle)</code>:如果要傳遞多個參數,推薦使用該方法。

<code>withbundle(string key, bundle bundle)</code>:依然是傳遞一個bundle,但可以自定義key .

<code>with封裝資料類型(string key, 基本資料類型值)</code>:如果隻傳遞一個參數,且是基本資料類型,那麼這些方法非常實用。

其他常使用的像傳遞序列化對象、集合等,大家自行嘗試。下面說下如何取參數。如下代碼是我們的<code>myinfoactivity</code>的傳參:

補充:可能有細心的朋友注意到,那帶傳回值方式的跳轉如何寫呢?

ARouter 在多 module 項目中實戰

第三個方法就等同于我們原生寫法<code>startactivityforresult()</code>

第四個方法還提供了監聽,後面要分享的攔截功能就會使用到。

取參說明

對應上面三個傳參方法:

<code>with(bundle bundle)</code>:取參數通過<code>getintent().getextras()</code>獲得bundle,然後就和我們原生用法相同。

<code>withbundle(string key, bundle bundle)</code> 和 <code>with封裝資料類型(string key, 基本資料類型值)</code>:取參數方式相同,可以先看一下上面給出的<code>myinfoactivity</code>的代碼:

可以看到這裡和我們平時取參數有幾點不同:

使用了<code>@autowired</code>注解

多了<code>arouter.getinstance().inject(this);</code>這行代碼

接收參數的字段都是<code>public</code>修飾符

并沒有顯式的getxxx取值代碼

對<code>@autowired</code>注解的說明:&lt;br/&gt;

所注解的變量必須是<code>public</code>的

如果變量的名字和傳參的key不相同,那麼需要手動給注解添加<code>name</code>值,即傳參的key.

除<code>with(bundle bundle)</code>這種方式傳參方式,其他方式要在接收參數的頁面添加下面這行代碼:

如果使用的<code>with(bundle bundle)</code>傳參方式,那麼取參數通過<code>getintent().getextras()</code>獲得bundle,操作即可。

綜合看起來,還是比較簡單的,少了很多判斷代碼。

這裡我使用<code>with(bundle bundle)</code>方式傳遞參數做示範。先來看一個總體的效果:

ARouter 在多 module 項目中實戰

這種方式傳遞參數,在接收的頁面上既不用添加<code>@autowired</code>注解,也不用添加<code>arouter.getinstance().inject(this);</code>這行代碼,使用我們原來的方式<code>getintent().getextras()</code>即可。

上面的示範效果中涉及<code>app</code>子產品跳轉<code>home</code>和<code>circle</code>子產品、<code>home</code>子產品和<code>circle</code>子產品互相跳轉,還記得前面的依賴關系嗎?<code>home</code>和<code>circle</code>直接是沒有依賴關系的,但可以通過路由直接跳轉,如果我們項目的module比較多,這就會很友善,降低代碼耦合性。

看一下跳轉<code>home</code>子產品的代碼:

核心代碼都貼出來了,到這基本的示範功能就完成了,本文是以<code>java</code>來示範的,<code>kotlin</code>配置參考官網。

關于路由的進階使用,比如:攔截以及子產品可單獨運作,下一篇部落格會揭曉。

arouter 通過注解自動注冊并且在編譯期間生成映射關系,在運作的時候就可以加載檔案,通過 path 就可以順利跳轉到目标頁面。

看不到對應的<code>r.layout.xxx_layout</code>檔案名了,可以通過點選<code>xxxbinding.getroot()</code>跳轉至對應xml

如果項目各子產品間跳轉比較多,建議統一使用路由跳轉

arouter還可以跳轉<code>fragment</code>,具體使用檢視官方demo

常見的跳轉動畫設定,arouter跳轉也是可以的,傳入動畫資源檔案id即可

本文全部代碼擷取:關注微信公衆号<code>code小生</code>回複<code>arouter</code>

</blockquote>