नेविगेशन कोड को मॉड्यूल में बांटना

इस पेज पर, नेविगेशन कोड को मॉड्यूल में बांटने के बारे में जानकारी दी गई है. इसका मकसद, ऐप्लिकेशन को मॉड्यूल में बांटने के बारे में सामान्य दिशा-निर्देशों के साथ-साथ जानकारी देना है.

खास जानकारी

नेविगेशन कोड को मॉड्यूल में बांटने का मतलब है कि एक जैसी नेविगेशन कुंजियों और उनसे जुड़े कॉन्टेंट को अलग-अलग मॉड्यूल में बांटना. इससे ज़िम्मेदारियों को अलग-अलग हिस्सों में बांटा जा सकता है. साथ ही, आपको अपने ऐप्लिकेशन में अलग-अलग सुविधाओं के बीच नेविगेट करने की सुविधा मिलती है.

अपने नेविगेशन कोड को मॉड्यूलर बनाने के लिए, यह तरीका अपनाएं:

  • अपने ऐप्लिकेशन की हर सुविधा के लिए, दो सबमॉड्यूल बनाएं: api और impl
  • हर सुविधा के लिए नेविगेशन कुंजियों को उसके api मॉड्यूल में रखें
  • हर सुविधा के लिए entryProviders और नेविगेट किए जा सकने वाले कॉन्टेंट को, उससे जुड़े impl मॉड्यूल में रखें
  • अपने मुख्य ऐप्लिकेशन मॉड्यूल को सीधे तौर पर या डिपेंडेंसी इंजेक्शन का इस्तेमाल करके entryProviders दें

सुविधाओं को एपीआई और लागू करने वाले सबमॉड्यूल में अलग-अलग करें

अपने ऐप्लिकेशन की हर सुविधा के लिए, api और impl नाम के दो सबमॉड्यूल बनाएं. impl का मतलब "लागू करना" है. यहां दी गई टेबल का इस्तेमाल करके, यह तय करें कि नेविगेशन कोड को कहां रखना है.

मॉड्यूल का नाम

इसमें शामिल है

api

नेविगेशन कुंजियां

impl

उस सुविधा के लिए कॉन्टेंट, जिसमें NavEntry और entryProvider की परिभाषाएं शामिल हैं. यह भी देखें कॉन्टेंट के लिए कुंजियां हल करना.

इस तरीके से, एक सुविधा से दूसरी सुविधा पर नेविगेट किया जा सकता है. इसके लिए, पहली सुविधा के impl मॉड्यूल में मौजूद कॉन्टेंट को दूसरी सुविधा के impl मॉड्यूल में मौजूद नेविगेशन कुंजियों पर निर्भर रहने की अनुमति दी जाती है.api

फ़ीचर मॉड्यूल की डिपेंडेंसी का डायग्राम. इसमें दिखाया गया है कि `impl` मॉड्यूल, `api` मॉड्यूल पर कैसे निर्भर कर सकते हैं.
पहली इमेज.
इस डायग्राम में, फ़ीचर मॉड्यूल की डिपेंडेंसी दिखाई गई है. इसमें बताया गया है कि एपीआई मॉड्यूल पर, इंप्लीमेंटेशन मॉड्यूल कैसे निर्भर कर सकते हैं.

एक्सटेंशन फ़ंक्शन का इस्तेमाल करके, नेविगेशन एंट्री को अलग करना

नेविगेशन 3 में, नेविगेट किए जा सकने वाले कॉन्टेंट को नेविगेशन एंट्री का इस्तेमाल करके तय किया जाता है. इन एंट्री को अलग-अलग मॉड्यूल में बांटने के लिए, 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 डीएसएल का इस्तेमाल किया जाता है. अगर आपके ऐप्लिकेशन में बहुत सारी स्क्रीन या सुविधा मॉड्यूल हैं, तो हो सकता है कि यह अच्छी तरह से स्केल न हो.

इस समस्या को हल करने के लिए, हर सुविधा मॉड्यूल को डिपेंडेंसी इंजेक्शन का इस्तेमाल करके, ऐप्लिकेशन की गतिविधि में अपने एंट्री बिल्डर का योगदान देना होगा.

उदाहरण के लिए, इस कोड में Dagger multibindings का इस्तेमाल किया गया है. खास तौर पर, @IntoSet का इस्तेमाल करके एंट्री बिल्डर को Set में इंजेक्ट किया गया है. इस 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() }
                },
                // ...
            )
        }
    }
}

अगर आपकी नेविगेशन एंट्री को नेविगेट करने की ज़रूरत है, जैसे कि उनमें ऐसे यूज़र इंटरफ़ेस (यूआई) एलिमेंट शामिल हैं जो नई स्क्रीन पर ले जाते हैं, तो ऐप्लिकेशन की नेविगेशन स्थिति में बदलाव करने में सक्षम ऑब्जेक्ट को हर बिल्डर फ़ंक्शन में इंजेक्ट करें.

संसाधन

Navigation 3 के कोड को मॉड्यूल में बांटने का तरीका बताने वाले कोड सैंपल के लिए, यहां जाएं: