Halaman ini adalah panduan untuk memodularisasi kode navigasi Anda. Tujuannya adalah untuk melengkapi panduan umum modularisasi aplikasi.
Ringkasan
Modularisasi kode navigasi adalah proses pemisahan kunci navigasi terkait, dan konten yang diwakilinya, ke dalam modul terpisah. Hal ini memberikan pemisahan tanggung jawab yang jelas dan memungkinkan Anda berpindah-pindah antara berbagai fitur di aplikasi.
Untuk memodularisasi kode navigasi Anda, lakukan hal berikut:
- Buat dua submodul:
apidanimpluntuk setiap fitur di aplikasi Anda - Tempatkan tombol navigasi untuk setiap fitur ke dalam modul
api-nya - Tempatkan
entryProvidersdan konten yang dapat dijelajahi untuk setiap fitur ke dalam modulimplterkait - Sediakan
entryProviderske modul aplikasi utama Anda, baik secara langsung maupun menggunakan injeksi dependensi
Memisahkan fitur ke dalam submodul API dan implementasi
Untuk setiap fitur di aplikasi Anda, buat dua submodule bernama api dan impl
(singkatan dari "implementasi"). Gunakan tabel berikut untuk memutuskan tempat menempatkan kode navigasi.
Nama modul |
Berisi |
|
|
|
Konten untuk fitur tersebut, termasuk definisi untuk
|
Pendekatan ini memungkinkan satu fitur menavigasi ke fitur lain dengan mengizinkan kontennya,
yang ada dalam modul impl, bergantung pada tombol navigasi modul lain, yang ada dalam modul api modul tersebut.
Memisahkan entri navigasi menggunakan fungsi ekstensi
Di Navigation 3, konten yang dapat dijelajahi ditentukan menggunakan entri navigasi. Untuk
memisahkan entri ini ke dalam modul terpisah, buat fungsi ekstensi di
EntryProviderScope dan pindahkan ke modul impl untuk fitur tersebut.
Fitur ini dikenal sebagai pembuat entri.
Contoh kode berikut menunjukkan pembuat entri yang membuat dua entri navigasi.
// 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 } } }
Panggil fungsi tersebut menggunakan DSL entryProvider saat menentukan
entryProvider di modul aplikasi utama.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
Menggunakan injeksi dependensi untuk menambahkan entri ke aplikasi utama
Dalam contoh kode sebelumnya, setiap builder entri dipanggil langsung oleh
aplikasi utama menggunakan DSL entryProvider. Jika aplikasi Anda memiliki banyak layar atau
modul fitur, pola ini mungkin tidak dapat diskalakan dengan baik.
Untuk mengatasinya, setiap modul fitur harus memberikan builder entri ke aktivitas aplikasi menggunakan injeksi dependensi.
Misalnya, kode berikut menggunakan multi-binding Dagger, khususnya @IntoSet, untuk menyuntikkan builder entri ke Set yang dimiliki oleh MainActivity. Kemudian, fungsi ini dipanggil secara iteratif di dalam entryProvider, sehingga tidak perlu memanggil banyak fungsi builder entri secara eksplisit.
Modul fitur
// 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() } }
Modul aplikasi
// 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() } }, // ... ) } } }
Jika entri navigasi Anda perlu melakukan navigasi—misalnya, entri tersebut berisi elemen UI yang melakukan navigasi ke layar baru—suntikkan objek yang dapat mengubah status navigasi aplikasi ke setiap fungsi builder.
Membuat pencocok deep link menjadi modular
Jika aplikasi Anda mendukung deep link dan dimodularisasi, setiap modul fitur
harus menentukan instance DeepLinkMatcher untuk tujuan yang dimilikinya.
Untuk mengumpulkan semua pencocokan dari seluruh aplikasi, Anda dapat menggunakan multibinding injeksi dependensi. Misalnya, setiap modul fitur dapat
memberikan pencocoknya ke multibinding Dagger @IntoSet:
Modul fitur
@Module @InstallIn(ActivityRetainedComponent::class) object FeatureADeepLinkModule { @IntoSet @Provides fun provideUserMatcher(): DeepLinkMatcher<*, *> { return UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ) } }
Kemudian, di modul aplikasi utama, seperti di MainActivity, Anda dapat menyuntikkan
kumpulan pencocok dan menggunakannya untuk mencocokkan permintaan yang masuk:
Modul aplikasi
@AndroidEntryPoint class MainActivityWithDI : ComponentActivity() { @Inject lateinit var deepLinkMatchers: Set<@JvmSuppressWildcards DeepLinkMatcher<*, *>> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val request = DeepLinkRequest(intent = intent) val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } .maxOrNull() val backStack = when (matchResult) { null -> listOf(HomeKey) is BackStackMatchResult<*, *> -> { @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } else -> listOf(matchResult.key) } } }
Untuk mengetahui informasi selengkapnya tentang cara menentukan dan menangani deep link, lihat Mendukung deep link.
Resource
Untuk contoh kode yang menunjukkan cara memodularisasi kode Navigation 3, lihat:
- Resep kode arsitektur Navigation 3
- Perjalanan pembelajaran modularisasi dari aplikasi Now in Android
- Androidify