واحدبندی کردن کد پیمایش

این صفحه راهنمایی برای واحدبندی کردن کد پیمایش شما است. این سند برای تکمیل راهنمای کلی برای واحدبندی برنامه درنظر گرفته شده است.

نمای کلی

واحدبندی کد پیمایش فرایند جدا کردن کلیدهای پیمایش مرتبط و محتوایی است که نشان می‌دهند به واحدهای جداگانه. این کار باعث می‌شود مسئولیت‌ها به‌طور واضح از هم جدا شوند و به شما امکان می‌دهد بین ویژگی‌های مختلف در برنامه‌تان پیمایش کنید.

برای مدولار کردن کد پیمایش، کارهای زیر را انجام دهید:

  • برای هر ویژگی در برنامه‌تان، دو زیرواحد api و impl ایجاد کنید
  • کلیدهای پیمایش را برای هر ویژگی در واحد api آن قرار دهید
  • entryProviders و محتوای پیمایش‌پذیر را برای هر ویژگی در واحد impl مرتبط قرار دهید
  • entryProviders را به واحدهای اصلی برنامه خود ارائه دهید، یا مستقیماً یا بااستفاده از تزریق وابستگی

ویژگی‌ها را به زیرواحد‌های api و پیاده‌سازی جدا کنید

برای هر ویژگی در برنامه‌تان، دو زیرواحد به نام‌های api و impl (کوته‌نوشت «پیاده‌سازی») ایجاد کنید. از جدول زیر برای تصمیم‌گیری درباره مکان کد پیمایش استفاده کنید.

نام واحد

شامل

api

کلیدهای پیمایش

impl

محتوای آن ویژگی، ازجمله تعاریف NavEntryها و entryProvider. همچنین کلیدها را به محتوا حل‌وفصل کنید را ببینید.

این رویکرد به یک ویژگی امکان می‌دهد با اجازه دادن به محتوای خود، که در واحد impl آن قرار دارد، به ویژگی دیگری که در واحد api آن قرار دارد، وابسته باشد و از کلیدهای پیمایش آن استفاده کند.

نمودار وابستگی واحد ویژگی که نشان می‌دهد واحدهای `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 همیاری کند:

واحد ویژگی

سپس، در واحد برنامه اصلی‌تان، مثلاً در MainActivity، می‌توانید مجموعه مطابقت‌دهنده‌ها را تزریق کنید و از آن‌ها برای مطابقت دادن درخواست‌های ورودی استفاده کنید:

واحد برنامه

برای کسب اطلاعات بیشتر درباره تعریف و مدیریت پیوندهای عمیق، پشتیبانی از پیوندهای عمیق را ببینید.

منابع

برای نمونه‌های کد که نحوه مدولار کردن کد «پیمایش ۳» را نشان می‌دهد، به این موارد مراجعه کنید: