این صفحه راهنمایی برای واحدبندی کردن کد پیمایش شما است. این سند برای تکمیل راهنمای کلی برای واحدبندی برنامه درنظر گرفته شده است.
نمای کلی
واحدبندی کد پیمایش فرایند جدا کردن کلیدهای پیمایش مرتبط و محتوایی است که نشان میدهند به واحدهای جداگانه. این کار باعث میشود مسئولیتها بهطور واضح از هم جدا شوند و به شما امکان میدهد بین ویژگیهای مختلف در برنامهتان پیمایش کنید.
برای مدولار کردن کد پیمایش، کارهای زیر را انجام دهید:
- برای هر ویژگی در برنامهتان، دو زیرواحد
apiوimplایجاد کنید - کلیدهای پیمایش را برای هر ویژگی در واحد
apiآن قرار دهید entryProvidersو محتوای پیمایشپذیر را برای هر ویژگی در واحدimplمرتبط قرار دهیدentryProvidersرا به واحدهای اصلی برنامه خود ارائه دهید، یا مستقیماً یا بااستفاده از تزریق وابستگی
ویژگیها را به زیرواحدهای api و پیادهسازی جدا کنید
برای هر ویژگی در برنامهتان، دو زیرواحد به نامهای api و impl
(کوتهنوشت «پیادهسازی») ایجاد کنید. از جدول زیر برای تصمیمگیری درباره مکان کد پیمایش استفاده کنید.
نام واحد |
شامل |
|
|
|
محتوای آن ویژگی، ازجمله تعاریف
|
این رویکرد به یک ویژگی امکان میدهد با اجازه دادن به محتوای خود،
که در واحد impl آن قرار دارد، به ویژگی دیگری
که در واحد api آن قرار دارد، وابسته باشد و از کلیدهای پیمایش آن استفاده کند.
جدا کردن ورودیهای پیمایش بااستفاده از توابع افزونه
در «پیمایش ۳»، محتوای پیمایشپذیر بااستفاده از ورودیهای پیمایش تعریف میشود. برای
جدا کردن این ورودیها در واحدهای جداگانه، توابع افزونه را در
EntryProviderScope ایجاد کنید و آنها را به واحد impl برای آن ویژگی منتقل کنید.
اینها بهعنوان سازندگان ورودی شناخته میشوند.
نمونه کد زیر سازنده ورودی را نشان میدهد که دو ورودی پیمایش میسازد.
// 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 } } }
هنگام تعریف entryProvider در واحد برنامه اصلی، بااستفاده از entryProvider DSL آن تابع را فراخوانی کنید.
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
برای افزودن ورودی به برنامه اصلی، از تزریق وابستگی استفاده کنید
در مثال کد قبلی، هر سازنده ورودی مستقیماً توسط
برنامه اصلی بااستفاده از entryProvider DSL فراخوانده میشود. اگر برنامه شما صفحههای زیادی دارد یا
واحد ویژگی، این الگو ممکن است بهخوبی مقیاسبندی نشود.
برای حل این مشکل، هر واحد ویژگی باید سازندگان ورودی خود را بااستفاده از تزریق وابستگی در فعالیت برنامه همیاری کند.
برای مثال، کد زیر از چندین اتصال Dagger، بهطور خاص @IntoSet، برای تزریق سازندگان ورودی به Set متعلق به MainActivity استفاده میکند. سپس اینها بهصورت تکراری در entryProvider فراخوانده میشوند و
نیاز به فراخوانی صریح توابع سازنده ورودی متعدد را ازبین میبرند.
واحد ویژگی
// 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() } }
واحد برنامه
// 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() } }, // ... ) } } }
اگر ورودیهای پیمایش شما نیاز به پیمایش دارند—برای مثال، حاوی عناصر رابط کاربری هستند که به صفحههای جدید پیمایش میکنند—شیئی را که قادر به اصلاح وضعیت پیمایش برنامه است به هر تابع سازنده تزریق کنید.
واحدبندی کردن مطابقتدهندههای پیوند عمیق
اگر برنامه شما از پیوندهای عمیق پشتیبانی میکند و واحدبندی شده است، هر واحد ویژگی باید نمونههای DeepLinkMatcher را برای مقاصدی که مالک آن است تعریف کند.
برای جمعآوری همه مطابقتدهندهها از سراسر برنامه، میتوانید از
چندین اتصال تزریق وابستگی استفاده کنید. برای مثال، هر واحد ویژگی میتواند
مطابقتدهندههای خود را به یک چندرابط Dagger @IntoSet همیاری کند:
واحد ویژگی
@Module @InstallIn(ActivityRetainedComponent::class) object FeatureADeepLinkModule { @IntoSet @Provides fun provideUserMatcher(): DeepLinkMatcher<*, *> { return UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ) } }
سپس، در واحد برنامه اصلیتان، مثلاً در MainActivity، میتوانید مجموعه مطابقتدهندهها را تزریق کنید و از آنها برای مطابقت دادن درخواستهای ورودی استفاده کنید:
واحد برنامه
@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) } } }
برای کسب اطلاعات بیشتر درباره تعریف و مدیریت پیوندهای عمیق، پشتیبانی از پیوندهای عمیق را ببینید.
منابع
برای نمونههای کد که نحوه مدولار کردن کد «پیمایش ۳» را نشان میدهد، به این موارد مراجعه کنید: