Phân chia mã điều hướng thành các phần

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: apiimpl cho 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 api tương ứng
  • Đặt entryProviders và nội dung có thể điều hướng cho từng tính năng vào mô-đun impl được liên kết
  • Cung cấp entryProviders cho 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à apiimpl (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

api

các phím điều hướng

impl

Nội dung cho tính năng đó, bao gồm cả định nghĩa về NavEntryentryProvider. Xem thêm giải quyết các khoá cho nội dung.

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 đó).

Sơ đồ phần phụ thuộc của mô-đun tính năng cho thấy cách các mô-đun "impl" có thể phụ thuộc vào các mô-đun "api".
Hình 1. Sơ đồ phần phụ thuộc của mô-đun tính năng cho thấy cách các mô-đun triển khai có thể phụ thuộc vào các mô-đun api.

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: