फ़ीचर मॉड्यूल की मदद से नेविगेट करें

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

सेटअप

सुविधा वाले मॉड्यूल पर काम करने के लिए, अपने ऐप्लिकेशन मॉड्यूल की build.gradle फ़ाइल में इन डिपेंडेंसी का इस्तेमाल करें:

ग्रूवी

dependencies {
    def nav_version = "2.8.0"

    api "androidx.navigation:navigation-fragment-ktx:$nav_version"
    api "androidx.navigation:navigation-ui-ktx:$nav_version"
    api "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
}

Kotlin

dependencies {
    val nav_version = "2.8.0"

    api("androidx.navigation:navigation-fragment-ktx:$nav_version")
    api("androidx.navigation:navigation-ui-ktx:$nav_version")
    api("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")
}

ध्यान दें कि अन्य नेविगेशन डिपेंडेंसी के लिए एपीआई कॉन्फ़िगरेशन का इस्तेमाल किया जाना चाहिए ताकि वे आपके फ़ीचर मॉड्यूल के लिए उपलब्ध हों.

बुनियादी इस्तेमाल

सुविधा वाले मॉड्यूल पर काम करने के लिए, पहले सभी इंस्टेंस बदलें NavHostFragment आपके ऐप्लिकेशन में androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment:

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
    app:navGraph="@navigation/nav_graph"
    ... />

इसके बाद, किसी भी <activity>, <fragment> याapp:moduleName आपके com.android.dynamic-feature मॉड्यूल में <navigation> डेस्टिनेशन DynamicNavHostFragment से जुड़े नेविगेशन ग्राफ़. यह एट्रिब्यूट, डाइनैमिक नेविगेटर लाइब्रेरी को बताता है कि डेस्टिनेशन आपके तय किए गए नाम वाले फ़ीचर मॉड्यूल से जुड़ा हुआ है.

<fragment
    app:moduleName="myDynamicFeature"
    android:id="@+id/featureFragment"
    android:name="com.google.android.samples.feature.FeatureFragment"
    ... />

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

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

इस यूज़र इंटरफ़ेस (यूआई) को पसंद के मुताबिक बनाने या इंस्टॉलेशन को मैन्युअल तरीके से मैनेज करने के लिए प्रोग्रेस को देखें, तो प्रोग्रेस फ़्रैगमेंट को पसंद के मुताबिक बनाना और इस विषय में, अनुरोध की स्थिति पर नज़र रखें.

जिन डेस्टिनेशन में app:moduleName नहीं होता है वे इसके बिना काम करते रहेंगे बदलाव करता है और इस तरह व्यवहार करता है जैसे आपका ऐप्लिकेशन सामान्य NavHostFragment का इस्तेमाल करता है.

प्रोग्रेस फ़्रैगमेंट को पसंद के मुताबिक बनाएं

हर नेविगेशन ग्राफ़ के लिए, प्रोग्रेस फ़्रैगमेंट लागू करने की प्रोसेस को बदला जा सकता है डेस्टिनेशन के आईडी पर app:progressDestination एट्रिब्यूट सेट करके का इस्तेमाल करें, ताकि इंस्टॉलेशन की प्रोग्रेस को मैनेज किया जा सके. आपकी पसंद के मुताबिक प्रोग्रेस गंतव्य होना चाहिए Fragment जो इनसे लिया गया है AbstractProgressFragment. आपको इंस्टॉलेशन के बारे में सूचनाएं पाने के लिए, ऐब्सट्रैक्ट तरीकों को बदलना होगा प्रोग्रेस, गड़बड़ियां, और अन्य इवेंट शामिल होते हैं. इसके बाद, इंस्टॉल किए जाने की प्रोगेस यहां दिखाई जा सकती है: आपकी पसंद का यूज़र इंटरफ़ेस (यूआई).

लागू होने वाला डिफ़ॉल्ट DefaultProgressFragment क्लास इस एपीआई का इस्तेमाल करके, इंस्टॉलेशन की प्रोग्रेस दिखाती है.

अनुरोध की स्थिति पर नज़र रखना

डाइनैमिक नेविगेटर लाइब्रेरी की मदद से, उपयोगकर्ता अनुभव (UX) फ़्लो को लागू किया जा सकता है. एक इंच मांग पर डिलीवरी के लिए UX के सबसे सही तरीके, जिसमें उपयोगकर्ता इंतज़ार करते समय पिछली स्क्रीन के संदर्भ में रहता है इंस्टॉल करने की प्रोसेस पूरी करें. इसका मतलब है कि आपको इंटरमीडिएट की जानकारी दिखाने की ज़रूरत नहीं है यूज़र इंटरफ़ेस (यूआई) या प्रोग्रेस फ़्रैगमेंट.

स्क्रीन पर, सबसे नीचे मौजूद नेविगेशन बार दिखेगा. इसमें एक आइकॉन मौजूद होगा, जिसमें
         कि फ़ीचर मॉड्यूल डाउनलोड हो रहा है
दूसरी इमेज. स्क्रीन, जिस पर नेविगेशन बार पर जाएं.

इस स्थिति में, आपकी ज़िम्मेदारी है कि इंस्टॉलेशन की सभी स्थितियों, प्रोग्रेस में बदलाव, गड़बड़ियों, और इसी तरह.

ब्लॉक न करने वाले इस नेविगेशन फ़्लो को शुरू करने के लिए, DynamicExtras ऑब्जेक्ट जिसमें DynamicInstallMonitor से NavController.navigate(), जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:

Kotlin

val navController = ...
val installMonitor = DynamicInstallMonitor()

navController.navigate(
    destinationId,
    null,
    null,
    DynamicExtras(installMonitor)
)

Java

NavController navController = ...
DynamicInstallMonitor installMonitor = new DynamicInstallMonitor();

navController.navigate(
    destinationId,
    null,
    null,
    new DynamicExtras(installMonitor);
)

navigate() को कॉल करने के तुरंत बाद, आपको installMonitor.isInstallRequired की मदद से देखा जा सकता है कि नेविगेट करने की कोशिश की गई सुविधा मॉड्यूल इंस्टॉलेशन में होना चाहिए.

  • अगर वैल्यू false है, तो इसका मतलब है कि सामान्य डेस्टिनेशन पर नेविगेट किया जा रहा है और कुछ और करना होगा.
  • अगर वैल्यू true है, तो आपको उस LiveData ऑब्जेक्ट को देखना शुरू करना चाहिए जो अब installMonitor.status में है. इस LiveData ऑब्जेक्ट से उत्सर्जन होता है SplitInstallSessionState Play Core लाइब्रेरी से अपडेट पाएं. इन अपडेट में इंस्टॉलेशन शामिल हैं इस्तेमाल करें जिन्हें यूज़र इंटरफ़ेस (यूआई) को अपडेट करने के लिए इस्तेमाल किया जा सकता है. सभी को मैनेज करना न भूलें प्रासंगिक स्थितियां जो Play की मुख्य गाइड, शामिल करना उपयोगकर्ता से पुष्टि करने का अनुरोध करना ऐसा करना ज़रूरी है.

    Kotlin

    val navController = ...
    val installMonitor = DynamicInstallMonitor()
    
    navController.navigate(
      destinationId,
      null,
      null,
      DynamicExtras(installMonitor)
    )
    
    if (installMonitor.isInstallRequired) {
      installMonitor.status.observe(this, object : Observer<SplitInstallSessionState> {
          override fun onChanged(sessionState: SplitInstallSessionState) {
              when (sessionState.status()) {
                  SplitInstallSessionStatus.INSTALLED -> {
                      // Call navigate again here or after user taps again in the UI:
                      // navController.navigate(destinationId, destinationArgs, null, null)
                  }
                  SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> {
                      SplitInstallManager.startConfirmationDialogForResult(...)
                  }
    
                  // Handle all remaining states:
                  SplitInstallSessionStatus.FAILED -> {}
                  SplitInstallSessionStatus.CANCELED -> {}
              }
    
              if (sessionState.hasTerminalStatus()) {
                  installMonitor.status.removeObserver(this);
              }
          }
      });
    }
    

    Java

    NavController navController = ...
    DynamicInstallMonitor installMonitor = new DynamicInstallMonitor();
    
    navController.navigate(
      destinationId,
      null,
      null,
      new DynamicExtras(installMonitor);
    )
    
    if (installMonitor.isInstallRequired()) {
      installMonitor.getStatus().observe(this, new Observer<SplitInstallSessionState>() {
          @Override
          public void onChanged(SplitInstallSessionState sessionState) {
              switch (sessionState.status()) {
                  case SplitInstallSessionStatus.INSTALLED:
                      // Call navigate again here or after user taps again in the UI:
                      // navController.navigate(mDestinationId, mDestinationArgs, null, null);
                      break;
                  case SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION:
                      SplitInstallManager.startConfirmationDialogForResult(...)
                      break;
    
                  // Handle all remaining states:
                  case SplitInstallSessionStatus.FAILED:
                      break;
                  case SplitInstallSessionStatus.CANCELED:
                      break;
              }
    
              if (sessionState.hasTerminalStatus()) {
                  installMonitor.getStatus().removeObserver(this);
              }
          }
      });
    }
    

इंस्टॉलेशन पूरा हो जाने पर, LiveData ऑब्जेक्ट उत्सर्जन करता है SplitInstallSessionStatus.INSTALLED स्थिति. फिर आपको कॉल करना चाहिए NavController.navigate() फिर से सेटअप करें. मॉड्यूल अब इंस्टॉल हो गया है, इसलिए कॉल अब सफल होता है और ऐप्लिकेशन उम्मीद के मुताबिक डेस्टिनेशन पर नेविगेट करता है.

टर्मिनल स्थिति पर पहुंचने के बाद, जैसे कि इंस्टॉलेशन पूरा होने पर या जब इंस्टॉल नहीं हो सका, तो मेमोरी से बचने के लिए, आपको अपना LiveData ऑब्ज़र्वर हटाना चाहिए लीक हो जाता है. यह जांच की जा सकती है कि स्टेटस, टर्मिनल की स्थिति को दिखाता है या नहीं. इसके लिए, SplitInstallSessionStatus.hasTerminalStatus().

AbstractProgressFragment देखें उदाहरण के लिए, इस ऑब्ज़र्वर को लागू करने का एक उदाहरण है.

शामिल ग्राफ़

डाइनैमिक नेविगेटर लाइब्रेरी, यहां दिए गए ग्राफ़ के साथ काम करती है: सुविधा वाले मॉड्यूल. किसी सुविधा में परिभाषित ग्राफ़ को शामिल करने के लिए मॉड्यूल की मदद से, ये काम किए जा सकते हैं:

  1. <include/> के बजाय <include-dynamic/> का इस्तेमाल करें, जैसा कि यहां दिखाया गया है उदाहरण:

    <include-dynamic
        android:id="@+id/includedGraph"
        app:moduleName="includedgraphfeature"
        app:graphResName="included_feature_nav"
        app:graphPackage="com.google.android.samples.dynamic_navigator.included_graph_feature" />
    
  2. <include-dynamic ... /> के अंदर, आपको नीचे दिए गए एट्रिब्यूट डालने होंगे:

    • app:graphResName: नेविगेशन ग्राफ़ रिसॉर्स फ़ाइल का नाम. कॉन्टेंट बनाने नाम ग्राफ़ की फ़ाइल के नाम से लिया गया है. उदाहरण के लिए, यदि ग्राफ़ res/navigation/nav_graph.xml, संसाधन का नाम nav_graph है.
    • android:id - ग्राफ़ का डेस्टिनेशन आईडी. डाइनैमिक नेविगेटर लाइब्रेरी इसके रूट एलिमेंट में मौजूद किसी भी android:id वैल्यू को अनदेखा कर देता है शामिल ग्राफ़.
    • app:moduleName: मॉड्यूल का पैकेज नाम.

सही ग्राफ़ पैकेज का इस्तेमाल करें

नेविगेशन के तौर पर app:graphPackage को सही होना ज़रूरी है कॉम्पोनेंट, सुविधा से बताए गए navGraph को शामिल नहीं कर पाएगा मॉड्यूल की ज़रूरत नहीं है.

किसी डाइनैमिक फ़ीचर मॉड्यूल का पैकेज नाम जोड़ने के लिए, बेस ऐप्लिकेशन मॉड्यूल के applicationId के मॉड्यूल का नाम. इसलिए, अगर बेस ऐप्लिकेशन मॉड्यूल में com.example.dynamicfeatureapp का applicationId और डाइनैमिक फ़ीचर मॉड्यूल को DynamicFeatureModule नाम दिया गया है. इसके बाद, पैकेज को नाम दिया गया है डाइनैमिक मॉड्यूल का नाम होगा com.example.dynamicfeatureapp.DynamicFeatureModule. इस पैकेज का नाम है केस-सेंसिटिव (बड़े और छोटे अक्षरों में अंतर) होता है.

अगर आपको कोई शक है, तो फ़ीचर मॉड्यूल के पैकेज के नाम की पुष्टि करें जनरेट किए गए AndroidManifest.xml की जांच करके. प्रोजेक्ट बनाने के बाद, <DynamicFeatureModule>/build/intermediates/merged_manifest/debug/AndroidManifest.xml तक, जो कुछ इस तरह दिखना चाहिए:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    featureSplit="DynamicFeatureModule"
    package="com.example.dynamicfeatureapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="21"
        android:targetSdkVersion="30" />

    <dist:module
        dist:instant="false"
        dist:title="@string/title_dynamicfeaturemodule" >
        <dist:delivery>
            <dist:install-time />
        </dist:delivery>

        <dist:fusing dist:include="true" />
    </dist:module>

    <application />

</manifest>

featureSplit की वैल्यू, डाइनैमिक सुविधा के मॉड्यूल के नाम से मेल खानी चाहिए. साथ ही, पैकेज, बेस ऐप्लिकेशन मॉड्यूल के applicationId से मेल खाएगा. app:graphPackage इनका कॉम्बिनेशन है: com.example.dynamicfeatureapp.DynamicFeatureModule.

आप सिर्फ़ इस आप के startDestination पर ही नेविगेट कर सकते हैं include-dynamic नेविगेशन ग्राफ़. डायनेमिक मॉड्यूल इसके लिए ज़िम्मेदार है खुद का नेविगेशन ग्राफ़ है और बेस ऐप्लिकेशन को इसके बारे में कोई जानकारी नहीं है.

डाइनैमिक शामिल करने की सुविधा की मदद से, बेस ऐप्लिकेशन मॉड्यूल में नेस्ट किया गया नेविगेशन ग्राफ़ जो डाइनैमिक मॉड्यूल में तय होता है. नेस्ट किया गया यह नेविगेशन ग्राफ़ काम करता है का इस्तेमाल किया जा सकता है. रूट नेविगेशन ग्राफ़ (यानी, पैरंट में नेस्ट किए गए नेविगेशन ग्राफ़) सिर्फ़ नेस्ट किए गए नेविगेशन ग्राफ़ को गंतव्य न हो, न कि उसके बच्चे. इस तरह, startDestination का इस्तेमाल तब किया जाता है, जब डाइनैमिक नेविगेशन शामिल करने वाला ग्राफ़, डेस्टिनेशन होता है.

सीमाएं

  • डाइनैमिक रूप से शामिल ग्राफ़, फ़िलहाल डीप लिंक के साथ काम नहीं करते.
  • डाइनैमिक रूप से लोड किए गए नेस्ट किए गए ग्राफ़ (यानी कि <navigation> एलिमेंट में app:moduleName) में फ़िलहाल डीप लिंक काम नहीं करते.