androidx navigation 2.3.0
加入了對 dynamic feature module
的導航支持,因此我們利用這個來分離出多個功能 module 來實現模塊化
國內基本不用的 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 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
接着我們在 activity_main 中設置默認的 host
這裏不同於正常 navigation 的用法,沒有使用 NavHostFragment,而是使用 DynamicNavHostFragment
直接跳轉 fragment
我們創建 dynamic feature module ,取名爲 feature1
創建 dynamic feature module
包名前部分需保證與 applicationId 相同
這裏 dynamic feature module
的包名前部分要和 applicationId 即 app module 包名相同,否則後續的 include 操作會有問題
這裏我們選擇在安裝時集成該 module
接着我們在該 module 下創建一個 fragment 取名爲 Feature1OneFragment
之後我們直接在 main_nav.xml 中引入 該 fragment 並加入 action
接着我們就可以在 app 下的 MainFragment 打開 Feature1OneFragment
我的 demo 中 feature2 是直接引入 fragment,因此跳轉的是 Feature2OneFragment
直接跳轉 activity
在 feature1 中創建 activity (demo 中爲 feature2)
同樣需要指定 moduleName
使用 dynamic feature module 內部的 graph
我們可以爲 dynamic feature module 單獨配置 navigation graph,這樣就可以處理 dynamic feature module 內部的跳轉了
在 feature1 中創建 feature1_nav.xml ,其中 startDestination 爲 Feature1OneFragment
在 main_nav.xml 我們需要使用另外一種方式來使用該 graph
include-dynamic
我們使用了一個新的標籤 include-dynamic
,同時我們看到了幾個沒用過的屬性
-
graphPackage
爲dynamic feature module
的包名 -
graphResName
爲dynamic feature module
內部 graph 的名字 -
moduleName
爲 module 名
注意:這裏的 graphPackage 可以省略
如果 module 的包名沒用按照前文的格式配置會導致無法找到 graphId 的異常
include-dynamic 標籤的 id 要與
feature1_nav.xml
navigation 標籤下的 id 一致,或者後者不設置 id
這樣從 app module 導航到 feature1 的 startDestination 後便可使用其內部的邏輯進行後續的導航了
feature module 間跳轉
Navigation 組件暫不支持 Dynamic include graph 的 deep link
因此我目前也沒有找到特別優雅的方式,已知的方案如下
-
反射
-
使用依賴注入