Thư viện Trình điều hướng động sẽ mở rộng chức năng của thành phần Điều hướng Jetpack để liên kết với các đích đến được xác định trong mô-đun tính năng. Thư viện này cũng cung cấp dịch vụ cài đặt liền mạch các mô-đun tính năng theo yêu cầu khi điều hướng đến những đích đến này.
Thiết lập
Để hỗ trợ các mô-đun tính năng, hãy sử dụng các phần phụ thuộc sau trong tệp build.gradle
của mô-đun ứng dụng:
Groovy
dependencies { def nav_version = "2.5.3" 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" }
Kotlin
dependencies { val nav_version = "2.5.3" 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") }
Lưu ý các phần phụ thuộc Điều hướng khác phải sử dụng cấu hình api để luôn khả dụng cho các mô-đun tính năng.
Cách sử dụng cơ bản
Để hỗ trợ các mô-đun tính năng, trước tiên hãy thay đổi tất cả các phiên bản của NavHostFragment
trong ứng dụng thành androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
app:navGraph="@navigation/nav_graph"
... />
Tiếp theo, hãy thêm thuộc tính app:moduleName
vào bất kỳ đích đến <activity>
, <fragment>
hoặc <navigation>
nào trong biểu đồ điều hướng của mô-đun com.android.dynamic-feature
được liên kết vớiDynamicNavHostFragment
.
Thuộc tính này báo cho thư viện Trình điều hướng động biết đích đến thuộc một mô-đun tính năng với tên đã được chỉ định.
<fragment
app:moduleName="myDynamicFeature"
android:id="@+id/featureFragment"
android:name="com.google.android.samples.feature.FeatureFragment"
... />
Khi bạn điều hướng đến một trong các đích đến này, trước tiên thư viện Trình điều hướng động sẽ kiểm tra xem mô-đun tính năng có được cài đặt hay không. Nếu đã có mô-đun tính năng, ứng dụng sẽ điều hướng đến đích đến như dự kiến. Nếu không có mô-đun, ứng dụng sẽ hiển thị một đích đến phân mảnh tiến trình trung gian khi cài đặt mô-đun. Cách triển khai mặc định của mảnh tiến trình sẽ hiển thị giao diện người dùng cơ bản ở thanh tiến trình và xử lý mọi lỗi cài đặt.

Để tùy chỉnh giao diện người dùng hoặc xử lý theo cách thủ công quá trình cài đặt từ trong màn hình ứng dụng, hãy xemTùy chỉnh phân mảnh tiến trình và Theo dõi trạng thái yêu cầu trong chủ đề này.
Các đích đến không chỉ định app:moduleName
vẫn tiếp tục hoạt động mà không có các thay đổi đồng thời chúng vận hành như thể ứng dụng sử dụng NavHostFragment
thông thường.
Tùy chỉnh phân mảnh tiến trình
Có thể ghi đè phương thức triển khai mảnh tiến trình cho từng biểu đồ điều hướng bằng cách đặt thuộc tính app:progressDestination
thành mã đích đến mà bạn muốn sử dụng để xử lý tiến trình cài đặt. đích đến tiến trình tùy chỉnh phải là Fragment
bắt nguồn từ AbstractProgressFragment
.
Bạn phải ghi đè các phương thức tóm tắt cho thông báo về tiến trình cài đặt, lỗi và các sự kiện khác. Sau đó, có thể hiển thị tiến trình cài đặt trong giao diện người dùng đã chọn
Lớp triển khai mặc định DefaultProgressFragment
sẽ sử dụng API này để hiển thị tiến trình cài đặt.
Theo dõi trạng thái của yêu cầu
Thư viện Trình điều hướng động cho phép triển khai một luồng UX (trải nghiệm người dùng) tương tự như trong các phương pháp hay nhất về UX (trải nghiệm người dùng) để phân phối theo yêu cầu, trong đó người dùng ở bối cảnh màn hình trước khi chờ quá trình cài đặt hoàn tất . Điều này có nghĩa là bạn không cần hiển thị giao diện người dùng trung gian hay mảnh tiến trình.

Trong trường hợp đó, bạn chịu trách nhiệm theo dõi và xử lý tất cả các trạng thái cài đặt cũng như thay đổi về tiến trình, lỗi, v.v.
Để bắt đầu luồng điều hướng không bị chặn này, hãy chuyển đối tượng DynamicExtras
có chứa DynamicInstallMonitor
đến NavController.navigate()
, như trong ví dụ sau:
Kotlin
val navController = ... val installMonitor = DynamicInstallMonitor() navController.navigate( destinationId, null, null, DynamicExtras(installMonitor) )
Java
NavController navController = ... DynamicInstallMonitor installMonitor = new DynamicInstallMonitor(); navController.navigate( destinationId, null, null, new DynamicExtras(installMonitor); )
Ngay sau khi gọi navigate()
, bạn phải kiểm tra giá trị của installMonitor.isInstallRequired
để xem liệu thao tác điều hướng đã thử có cài đặt mô-đun tính năng hay không.
- Nếu giá trị là
false
, tức là bạn đang điều hướng đến một đích đến bình thường và không cần làm gì thêm. Nếu giá trị là
true
, bạn phải bắt đầu quan sát đối tượngLiveData
hiện có tronginstallMonitor.status
. Đối tượngLiveData
này phát raSplitInstallSessionState
nội dung cập nhật từ thư viện Play Core. Những bản cập nhật này chứa các sự kiện tiến trình cài đặt mà bạn có thể sử dụng để cập nhật giao diện người dùng. Hãy nhớ xử lý mọi trạng thái liên quan như đã nêu trong hướng dẫn Play Core, bao gồm yêu cầu người dùng xác nhận nếu cần thiết.Kotlin
val navController = ... val installMonitor = DynamicInstallMonitor() navController.navigate( destinationId, null, null, DynamicExtras(installMonitor) ) if (installMonitor.isInstallRequired) { installMonitor.status.observe(this, object : Observer<SplitInstallSessionState> { override fun onChanged(sessionState: SplitInstallSessionState) { when (sessionState.status()) { SplitInstallSessionStatus.INSTALLED -> { // Call navigate again here or after user taps again in the UI: // navController.navigate(destinationId, destinationArgs, null, null) } SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> { SplitInstallManager.startConfirmationDialogForResult(...) } // Handle all remaining states: SplitInstallSessionStatus.FAILED -> {} SplitInstallSessionStatus.CANCELED -> {} } if (sessionState.hasTerminalStatus()) { installMonitor.status.removeObserver(this); } } }); }
Java
NavController navController = ... DynamicInstallMonitor installMonitor = new DynamicInstallMonitor(); navController.navigate( destinationId, null, null, new DynamicExtras(installMonitor); ) if (installMonitor.isInstallRequired()) { installMonitor.getStatus().observe(this, new Observer<SplitInstallSessionState>() { @Override public void onChanged(SplitInstallSessionState sessionState) { switch (sessionState.status()) { case SplitInstallSessionStatus.INSTALLED: // Call navigate again here or after user taps again in the UI: // navController.navigate(mDestinationId, mDestinationArgs, null, null); break; case SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION: SplitInstallManager.startConfirmationDialogForResult(...) break; // Handle all remaining states: case SplitInstallSessionStatus.FAILED: break; case SplitInstallSessionStatus.CANCELED: break; } if (sessionState.hasTerminalStatus()) { installMonitor.getStatus().removeObserver(this); } } }); }
Khi quá trình cài đặt kết thúc, đối tượng LiveData
sẽ phát ra trạng thái SplitInstallSessionStatus.INSTALLED
. Sau đó, bạn phải gọi lại hàm NavController.navigate()
. Vì hiện mô-đun đã được cài đặt nên cuộc gọi sẽ thành công và ứng dụng sẽ điều hướng đến đích như mong đợi.
Sau khi đạt đến trạng thái đầu cuối, chẳng hạn như khi cài đặt xong hoặc khi cài đặt không thành công, bạn nên xóa bộ quan sát LiveData
để tránh bị rò rỉ bộ nhớ. Có thể kiểm tra xem trạng thái của thiết bị đầu cuối có đại diện cho một trạng thái đầu cuối nào hay không bằng cách sử dụng SplitInstallSessionStatus.hasTerminalStatus()
.
Hãy xem AbstractProgressFragment
để biết ví dụ về cách triển khai trình quan sát này.
Biểu đồ đi kèm
Thư viện Trình điều hướng động hỗ trợ cả biểu đồ được xác định trong các mô-đun tính năng. Để sử dụng một biểu đồ được xác định trong mô-đun tính năng, hãy làm như sau:
Sử dụng
<include-dynamic/>
thay vì<include/>
, như hiển thị ở ví dụ sau:<include-dynamic android:id="@+id/includedGraph" app:moduleName="includedgraphfeature" app:graphResName="included_feature_nav" app:graphPackage="com.google.android.samples.dynamic_navigator.included_graph_feature" />
Bên trong
<include-dynamic ... />
, bạn phải chỉ định các thuộc tính sau:app:graphResName
: tên của tệp tài nguyên biểu đồ điều hướng. Tên lấy từ tên tệp của biểu đồ. Ví dụ: nếu biểu đồ nằm trongres/navigation/nav_graph.xml
, thì tên tài nguyên lànav_graph
.android:id
– mã đích đến của biểu đồ. Thư viện Trình điều hướng động bỏ qua mọi giá trịandroid:id
được tìm thấy trong phần tử gốc của biểu đồ đi kèm.app:moduleName
: tên gói của mô-đun.
Sử dụng đúng graphPack
Bạn phải lấy app:graphPackage
chính xác, nếu không thành phần Điều hướng sẽ không thể bao gồm navGraph
được chỉ định từ mô-đun tính năng.
Tên gói của một mô-đun tính năng linh hoạt được tạo bằng cách thêm tên của mô-đun vào applicationId
của mô-đun ứng dụng cơ sở. Vì vậy, nếu mô-đun ứng dụng cơ sở có applicationId
trêncom.example.dynamicfeatureapp
và mô-đun tính năng linh hoạt được đặt tên là DynamicFeatureModule
, tên gói của mô-đun linh hoạt sẽ làcom.example.dynamicfeatureapp.DynamicFeatureModule
. Tên gói này có phân biệt chữ hoa và chữ thường.
Nếu không chắc chắn, bạn có thể xác nhận tên gói của mô-đun tính năng bằng cách kiểm tra AndroidManifest.xml
được tạo. Sau khi tạo dự án, hãy truy cập vào <DynamicFeatureModule>/build/intermediates/merged_manifest/debug/AndroidManifest.xml
, mã này có dạng như sau:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution" featureSplit="DynamicFeatureModule" package="com.example.dynamicfeatureapp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <dist:module dist:instant="false" dist:title="@string/title_dynamicfeaturemodule" > <dist:delivery> <dist:install-time /> </dist:delivery> <dist:fusing dist:include="true" /> </dist:module> <application /> </manifest>
Giá trị featureSplit
phải khớp với tên của mô-đun tính năng linh hoạt, còn gói sẽ khớp với applicationId
của mô-đun ứng dụng cơ sở. app:graphPackage
là sự kết hợp của các giá trị này: com.example.dynamicfeatureapp.DynamicFeatureModule
.
Chuyển đến biểu đồ điều hướng linh hoạt
Bạn chỉ có thể chuyển đến startDestination
của biểu đồ điều hướng include-dynamic
. Mô-đun linh hoạt chịu trách nhiệm về biểu đồ điều hướng của riêng ứng dụng đó, và ứng dụng cơ sở không nhận biết điều đó.
Cơ chế linh hoạt cho phép mô-đun ứng dụng cơ sở liên kết biểu đồ điều hướng lồng nhau được xác định trong mô-đun linh hoạt. Biểu đồ điều hướng lồng nhau này cũng hoạt động giống các biểu đồ điều hướng lồng nhau khác. Biểu đồ điều hướng gốc (nghĩa là biểu đồ gốc của biểu đồ điều hướng lồng nhau) chỉ có thể xác định chính biểu đồ điều hướng lồng nhau dưới dạng một đích đến chứ không phải là đích đến con của biểu đồ đó. Do đó, startDestination
được sử dụng khi biểu đồ điều hướng linh hoạt là đích đến.
Giới hạn
- Biểu đồ động hiện không hỗ trợ liên kết sâu.
- Biểu đồ lồng nhau chủ động tải linh hoạt (nghĩa là phần tử
<navigation>
cóapp:moduleName
) hiện không hỗ trợ liên kết sâu.