Trang này là hướng dẫn về cách mô-đun hoá mã điều hướng. Tài liệu này nhằm bổ sung cho hướng dẫn chung về việc mô-đun hoá ứng dụng.
Tổng quan
Mô-đun hoá mã điều hướng là quá trình tách các khoá điều hướng có liên quan và nội dung mà các khoá đó đại diện thành các mô-đun riêng lẻ. Điều này giúp phân tách rõ ràng các trách nhiệm và cho phép bạn di chuyển giữa các tính năng khác nhau trong ứng dụng.
Để phân chia mã điều hướng thành các mô-đun, hãy làm như sau:
- Tạo 2 mô-đun con:
apivàimplcho mỗi tính năng trong ứng dụng - Đặt các khoá điều hướng cho từng tính năng vào mô-đun
apitương ứng - Đặt
entryProvidersvà nội dung có thể điều hướng cho từng tính năng vào mô-đunimplđược liên kết - Cung cấp
entryProviderscho các mô-đun ứng dụng chính của bạn, dù là trực tiếp hay bằng cách sử dụng tính năng chèn phần phụ thuộc
Tách các tính năng thành các mô-đun con triển khai và API
Đối với mỗi tính năng trong ứng dụng, hãy tạo 2 mô-đun con có tên là api và impl (viết tắt của "triển khai"). Hãy sử dụng bảng sau để quyết định vị trí đặt mã điều hướng.
Tên mô-đun |
Chứa |
|
|
|
Nội dung cho tính năng đó, bao gồm cả định nghĩa về |
Phương pháp này cho phép một tính năng chuyển đến một tính năng khác bằng cách cho phép nội dung của tính năng đó (nằm trong mô-đun impl) phụ thuộc vào các khoá điều hướng của một mô-đun khác (nằm trong mô-đun api của mô-đun đó).
Phân tách các mục nhập điều hướng bằng cách sử dụng hàm mở rộng
Trong Navigation 3, nội dung có thể điều hướng được xác định bằng cách sử dụng các mục điều hướng. Để tách các mục này thành các mô-đun riêng biệt, hãy tạo các hàm mở rộng trên EntryProviderScope rồi di chuyển chúng vào mô-đun impl cho tính năng đó.
Đây được gọi là trình tạo mục nhập.
Ví dụ về mã sau đây cho thấy một trình tạo mục nhập tạo ra 2 mục nhập điều hướng.
// import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey fun EntryProviderScope<NavKey>.featureAEntryBuilder() { entry<KeyA> { ContentRed("Screen A") { // Content for screen A } } entry<KeyA2> { ContentGreen("Screen A2") { // Content for screen A2 } } }
Gọi hàm đó bằng cách sử dụng DSL entryProvider khi xác định entryProvider trong mô-đun ứng dụng chính.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
Sử dụng tính năng chèn phần phụ thuộc để thêm các mục vào ứng dụng chính
Trong ví dụ về mã trước đó, mỗi trình tạo mục nhập được ứng dụng chính gọi trực tiếp bằng cách sử dụng DSL entryProvider. Nếu ứng dụng của bạn có nhiều màn hình hoặc mô-đun tính năng, thì điều này có thể không mở rộng tốt.
Để giải quyết vấn đề này, hãy để mỗi mô-đun tính năng đóng góp các trình tạo mục nhập của mô-đun đó vào hoạt động của ứng dụng bằng cách sử dụng tính năng chèn phần phụ thuộc.
Ví dụ: mã sau đây sử dụng Dagger multibindings, cụ thể là @IntoSet, để chèn các trình tạo mục nhập vào một Set do MainActivity sở hữu. Sau đó, các hàm này được gọi lặp đi lặp lại bên trong entryProvider, loại bỏ nhu cầu gọi rõ ràng nhiều hàm tạo mục nhập.
Mô-đun tính năng
// import dagger.Module // import dagger.Provides // import dagger.hilt.InstallIn // import dagger.hilt.android.components.ActivityRetainedComponent // import dagger.multibindings.IntoSet @Module @InstallIn(ActivityRetainedComponent::class) object FeatureAModule { @IntoSet @Provides fun provideFeatureAEntryBuilder() : EntryProviderScope<NavKey>.() -> Unit = { featureAEntryBuilder() } }
Mô-đun ứng dụng
// import android.os.Bundle // import androidx.activity.ComponentActivity // import androidx.activity.compose.setContent // import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey // import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay // import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject lateinit var entryBuilders: Set<@JvmSuppressWildcards EntryProviderScope<NavKey>.() -> Unit> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NavDisplay( entryProvider = entryProvider { entryBuilders.forEach { builder -> this.builder() } }, // ... ) } } }
Nếu các mục điều hướng của bạn cần điều hướng (ví dụ: chúng chứa các phần tử trên giao diện người dùng điều hướng đến màn hình mới), hãy chèn một đối tượng có khả năng sửa đổi trạng thái điều hướng của ứng dụng vào từng hàm trình tạo.
Tài nguyên
Để xem các đoạn mã mẫu minh hoạ cách phân chia mã Điều hướng 3 thành các mô-đun, hãy xem:
- Các công thức mã kiến trúc Navigation 3
- Hành trình học tập về việc mô-đun hoá từ ứng dụng Now in Android
- Androidify