使用 Navigation + Dynamic Feature Module 實現模塊化

androidx navigation 2.3.0 加入了對 dynamic feature module 的導航支持,因此我們利用這個來分離出多個功能 module 來實現模塊化

navigation 2.3.0 更新

國內基本不用的 dynamic feature module

Android App Bundle 是官方 18 年推出的動態發佈方案,類似國內各種插件化方案。不過它需要 Google Play Store 支持,這導致在國內無法使用

藉着 navigation 組件支持 dynamic feature module 間導航的契機,我們可以使用 dynamic feature module 來拆分功能模塊以實現模塊化

傳統的拆分方案大概是這樣,feature module 之間相互隔離,app module 依賴各個 feature module 間接依賴 base 庫,公共庫

傳統架構

而使用 dynamic feature module ,其結構是這樣的

dynamic feature 架構

dynamic feature module 也可以按需安裝,也就是說,它們可能不包含在用戶最初下載的 APK 中,而是在運行時安裝。而我們可以直接將它們包含到 APK 中

使用 dynamic feature module

首先我們在 base lib 中引入依賴

dependencies {
    def nav_version = "2.3.0-alpha06"

    api "androidx.navigation:navigation-fragment-ktx:$nav_version"
    api "androidx.navigation:navigation-ui-ktx:$nav_version"
    api "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
}

我們在 app module 中的 res/navigation 目錄下創建 main_nav.xml

main_nav.xml

接着我們在 activity_main 中設置默認的 host

默認 host

這裏不同於正常 navigation 的用法,沒有使用 NavHostFragment,而是使用 DynamicNavHostFragment

直接跳轉 fragment

我們創建 dynamic feature module ,取名爲 feature1

創建 dynamic feature module

創建 dynamic feature module

包名前部分需保證與 applicationId 相同

包名前部分需保證與 applicationId 相同

這裏 dynamic feature module 的包名前部分要和 applicationId 即 app module 包名相同,否則後續的 include 操作會有問題

選擇加載模式

這裏我們選擇在安裝時集成該 module

接着我們在該 module 下創建一個 fragment 取名爲 Feature1OneFragment

之後我們直接在 main_nav.xml 中引入 該 fragment 並加入 action

直接引入 fragment

接着我們就可以在 app 下的 MainFragment 打開 Feature1OneFragment

啓動 fragment

 

我的 demo 中 feature2 是直接引入 fragment,因此跳轉的是 Feature2OneFragment

直接跳轉 activity

在 feature1 中創建 activity (demo 中爲 feature2)

跳轉 activity

同樣需要指定 moduleName

啓動activity

使用 dynamic feature module 內部的 graph

我們可以爲 dynamic feature module 單獨配置 navigation graph,這樣就可以處理 dynamic feature module 內部的跳轉了

在 feature1 中創建 feature1_nav.xml ,其中 startDestination 爲 Feature1OneFragment

feature1_nav.xml

在 main_nav.xml 我們需要使用另外一種方式來使用該 graph

include-dynamic

include-dynamic

我們使用了一個新的標籤 include-dynamic,同時我們看到了幾個沒用過的屬性

  • graphPackagedynamic feature module 的包名

  • graphResNamedynamic feature module 內部 graph 的名字

  • moduleName 爲 module 名

注意:這裏的 graphPackage 可以省略
  1. 如果 module 的包名沒用按照前文的格式配置會導致無法找到 graphId 的異常

  2. include-dynamic 標籤的 id 要與 feature1_nav.xml navigation 標籤下的 id 一致,或者後者不設置 id

這樣從 app module 導航到 feature1 的 startDestination 後便可使用其內部的邏輯進行後續的導航了

include 跳轉

feature module 間跳轉

暫不支持 deep link

Navigation 組件暫不支持 Dynamic include graph 的 deep link

因此我目前也沒有找到特別優雅的方式,已知的方案如下

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章