मांग पर डिलीवरी कॉन्फ़िगर करना

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

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

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

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

इस पेज से, आपको अपने ऐप्लिकेशन प्रोजेक्ट में एक फ़ीचर मॉड्यूल जोड़ने और मांग पर डिलीवरी के लिए इसे कॉन्फ़िगर करने में मदद मिलती है. शुरू करने से पहले, पक्का करें कि आपके पास Android Studio 3.5 या इसके बाद का वर्शन और Android Gradle प्लग इन 3.5.0 या इसके बाद का वर्शन हो.

मांग पर डिलीवरी के लिए नया मॉड्यूल कॉन्फ़िगर करना

नया फ़ीचर मॉड्यूल बनाने का सबसे आसान तरीका, Android Studio 3.5 या इसके बाद के वर्शन का इस्तेमाल करना है. फ़ीचर मॉड्यूल, बुनियादी ऐप्लिकेशन मॉड्यूल पर निर्भर होते हैं. इसलिए, इन्हें सिर्फ़ मौजूदा ऐप्लिकेशन प्रोजेक्ट में जोड़ा जा सकता है.

Android Studio का इस्तेमाल करके, अपने ऐप्लिकेशन प्रोजेक्ट में सुविधा मॉड्यूल जोड़ने के लिए, यह तरीका अपनाएं:

  1. अगर आपने अब तक ऐसा नहीं किया है, तो IDE में अपना ऐप्लिकेशन प्रोजेक्ट खोलें.
  2. मेन्यू बार में जाकर, फ़ाइल > नया > नया मॉड्यूल चुनें.
  3. नया मॉड्यूल बनाएं डायलॉग में, डाइनैमिक फ़ीचर मॉड्यूल को चुनें और आगे बढ़ें पर क्लिक करें.
  4. अपना नया मॉड्यूल कॉन्फ़िगर करें सेक्शन में, ये काम करें:
    1. ड्रॉपडाउन मेन्यू से, अपने ऐप्लिकेशन प्रोजेक्ट के लिए बेस ऐप्लिकेशन मॉड्यूल चुनें.
    2. मॉड्यूल का नाम डालें. IDE इस नाम का इस्तेमाल करके, Gradle सेटिंग फ़ाइल में मॉड्यूल को Gradle सब-प्रोजेक्ट के तौर पर पहचानता है. ऐप्लिकेशन बंडल बनाने पर, Gradle सुविधा वाले मॉड्यूल के मेनिफ़ेस्ट में <manifest split> एट्रिब्यूट को इंजेक्ट करने के लिए, सब-प्रोजेक्ट के नाम के आखिरी एलिमेंट का इस्तेमाल करता है.
    3. मॉड्यूल का पैकेज का नाम बताएं. डिफ़ॉल्ट रूप से, Android Studio एक ऐसे पैकेज नाम का सुझाव देता है जो बेस मॉड्यूल के रूट पैकेज के नाम और पिछले चरण में बताए गए मॉड्यूल के नाम को मिलाकर बना देता है.
    4. वह कम से कम एपीआई लेवल चुनें जिस पर आपको मॉड्यूल का इस्तेमाल करना है. यह वैल्यू, बेस मॉड्यूल की वैल्यू से मेल खानी चाहिए.
  5. आगे बढ़ें पर क्लिक करें.
  6. मॉड्यूल डाउनलोड के विकल्प सेक्शन में, इन चीज़ों को पूरा करें:

    1. ज़्यादा से ज़्यादा 50 वर्णों का इस्तेमाल करके, मॉड्यूल का टाइटल डालें. प्लैटफ़ॉर्म, उपयोगकर्ताओं को मॉड्यूल की पहचान करने के लिए इस टाइटल का इस्तेमाल करता है. उदाहरण के लिए, यह पुष्टि करने के लिए कि उपयोगकर्ता को मॉड्यूल डाउनलोड करना है या नहीं. इस वजह से, आपके ऐप्लिकेशन के बेस मॉड्यूल में, मॉड्यूल का टाइटल स्ट्रिंग रिसॉर्स के तौर पर शामिल होना चाहिए. इस टाइटल का अनुवाद किया जा सकता है. Android Studio का इस्तेमाल करके मॉड्यूल बनाते समय, IDE आपके लिए बेस मॉड्यूल में स्ट्रिंग रिसॉर्स जोड़ता है. साथ ही, सुविधा मॉड्यूल के मेनिफ़ेस्ट में यह एंट्री इंजेक्ट करता है:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. इंस्टॉल करते समय मॉड्यूल शामिल न करें के नीचे दिए गए ड्रॉपडाउन मेन्यू में, इंस्टॉल के समय मॉड्यूल शामिल न करें चुनें. आपकी पसंद को दिखाने के लिए, Android Studio मॉड्यूल के मेनिफ़ेस्ट में ये चीज़ें इंजेक्ट करता है:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. अगर आपको यह मॉड्यूल Android 4.4 (एपीआई लेवल 20) और उससे पहले के वर्शन वाले डिवाइसों पर उपलब्ध कराना है और मल्टी-APKs में शामिल करना है, तो Fused के आगे मौजूद बॉक्स पर सही का निशान लगाएं. इसका मतलब है कि इस मॉड्यूल के लिए, मांग पर काम करने की सुविधा चालू की जा सकती है. साथ ही, फ़्यूज़ करने की सुविधा बंद करके, इसे उन डिवाइसों से हटाया जा सकता है जिन पर स्प्लिट APK डाउनलोड और इंस्टॉल करने की सुविधा काम नहीं करती. आपकी पसंद को दिखाने के लिए, Android Studio मॉड्यूल के मेनिफ़ेस्ट में ये चीज़ें इंजेक्ट करता है:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. पूरा करें पर क्लिक करें.

Android Studio आपका मॉड्यूल बनाने के बाद, प्रोजेक्ट पैनल में जाकर, अपने कॉन्टेंट की जांच करें. इसके लिए, मेन्यू बार से व्यू > टूल विंडो > प्रोजेक्ट चुनें. डिफ़ॉल्ट कोड, रिसॉर्स, और संगठन, स्टैंडर्ड ऐप्लिकेशन मॉड्यूल के जैसे होने चाहिए.

इसके बाद, आपको Play Feature Delivery लाइब्रेरी का इस्तेमाल करके, मांग पर इंस्टॉल करने की सुविधा लागू करनी होगी.

अपने प्रोजेक्ट में Play Feature Delivery लाइब्रेरी शामिल करना

शुरू करने से पहले, आपको अपने प्रोजेक्ट में सबसे पहले Play की सुविधा डिलीवरी लाइब्रेरी जोड़नी होगी.

मांग पर उपलब्ध मॉड्यूल का अनुरोध करना

जब आपके ऐप्लिकेशन को किसी सुविधा वाले मॉड्यूल का इस्तेमाल करना हो, तो वह SplitInstallManager क्लास की मदद से, फ़ोरग्राउंड में रहते हुए अनुरोध कर सकता है. अनुरोध करते समय, आपके ऐप्लिकेशन को मॉड्यूल का नाम बताना होगा. यह नाम, टारगेट मॉड्यूल के मेनिफ़ेस्ट में split एलिमेंट के तौर पर तय किया गया होता है. Android Studio का इस्तेमाल करके कोई फ़ीचर मॉड्यूल बनाने पर, बिल्ड सिस्टम उस मॉड्यूल के नाम का इस्तेमाल करता है जो कंपाइलेशन के समय इस प्रॉपर्टी को मॉड्यूल के मेनिफ़ेस्ट में इंजेक्ट करने के लिए किया जाता है. ज़्यादा जानकारी के लिए, सुविधा वाले मॉड्यूल के मेनिफ़ेस्ट के बारे में पढ़ें.

उदाहरण के लिए, ऐसा ऐप्लिकेशन जिसमें डिवाइस के कैमरे का इस्तेमाल करके फ़ोटो मैसेज कैप्चर करने और भेजने के लिए, मांग पर उपलब्ध मॉड्यूल मौजूद होता है. यह मांग पर मॉड्यूल के मेनिफ़ेस्ट में split="pictureMessages" के बारे में जानकारी देता है. यहां दिए गए सैंपल में, pictureMessages मॉड्यूल का अनुरोध करने के लिए SplitInstallManager का इस्तेमाल किया गया है. साथ ही, कुछ प्रमोशनल फ़िल्टर के लिए एक अतिरिक्त मॉड्यूल भी इस्तेमाल किया गया है:

Kotlin

// Creates an instance of SplitInstallManager.
val splitInstallManager = SplitInstallManagerFactory.create(context)

// Creates a request to install a module.
val request =
    SplitInstallRequest
        .newBuilder()
        // You can download multiple on demand modules per
        // request by invoking the following method for each
        // module you want to install.
        .addModule("pictureMessages")
        .addModule("promotionalFilters")
        .build()

splitInstallManager
    // Submits the request to install the module through the
    // asynchronous startInstall() task. Your app needs to be
    // in the foreground to submit the request.
    .startInstall(request)
    // You should also be able to gracefully handle
    // request state changes and errors. To learn more, go to
    // the section about how to Monitor the request state.
    .addOnSuccessListener { sessionId -> ... }
    .addOnFailureListener { exception ->  ... }

Java

// Creates an instance of SplitInstallManager.
SplitInstallManager splitInstallManager =
    SplitInstallManagerFactory.create(context);

// Creates a request to install a module.
SplitInstallRequest request =
    SplitInstallRequest
        .newBuilder()
        // You can download multiple on demand modules per
        // request by invoking the following method for each
        // module you want to install.
        .addModule("pictureMessages")
        .addModule("promotionalFilters")
        .build();

splitInstallManager
    // Submits the request to install the module through the
    // asynchronous startInstall() task. Your app needs to be
    // in the foreground to submit the request.
    .startInstall(request)
    // You should also be able to gracefully handle
    // request state changes and errors. To learn more, go to
    // the section about how to Monitor the request state.
    .addOnSuccessListener(sessionId -> { ... })
    .addOnFailureListener(exception -> { ... });

जब आपका ऐप्लिकेशन, मांग पर उपलब्ध किसी मॉड्यूल का अनुरोध करता है, तब Play Feature Delivery Library “फ़ायर-ऐंड-फ़ॉरवर्ड” रणनीति का इस्तेमाल करती है. इसका मतलब है कि यह प्लैटफ़ॉर्म पर मॉड्यूल डाउनलोड करने का अनुरोध भेजता है, लेकिन यह निगरानी नहीं करता कि इंस्टॉलेशन पूरा हुआ या नहीं. इंस्टॉलेशन के बाद, उपयोगकर्ता अनुभव को आगे बढ़ाने या गड़बड़ियों को ठीक से मैनेज करने के लिए, पक्का करें कि आपने अनुरोध की स्थिति पर नज़र रखी हो.

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

मॉड्यूल के कोड और संसाधनों को ऐक्सेस करने के लिए, आपके ऐप्लिकेशन को SplitCompat को चालू करना होगा. ध्यान दें कि Android इंस्टैंट ऐप्लिकेशन के लिए, SplitCompat का इस्तेमाल करना ज़रूरी नहीं है.

मांग पर मिलने वाले मॉड्यूल इंस्टॉल करने की प्रोसेस को रोकना

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

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

Kotlin

// Requests an on demand module to be downloaded when the app enters
// the background. You can specify more than one module at a time.
splitInstallManager.deferredInstall(listOf("promotionalFilters"))

Java

// Requests an on demand module to be downloaded when the app enters
// the background. You can specify more than one module at a time.
splitInstallManager.deferredInstall(Arrays.asList("promotionalFilters"));

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

अनुरोध की स्थिति को मॉनिटर करना

प्रोग्रेस बार को अपडेट करने, इंस्टॉलेशन के बाद इंटेंट को ट्रिगर करने या अनुरोध से जुड़ी गड़बड़ी को ठीक करने के लिए, आपको एसिंक्रोनस SplitInstallManager.startInstall() टास्क से स्टेटस अपडेट सुनने होंगे. इंस्टॉल के अनुरोध के लिए अपडेट पाने से पहले, एक Listener रजिस्टर करें और अनुरोध के लिए सेशन आईडी पाएं, जैसा कि यहां दिखाया गया है.

Kotlin

// Initializes a variable to later track the session ID for a given request.
var mySessionId = 0

// Creates a listener for request status updates.
val listener = SplitInstallStateUpdatedListener { state ->
    if (state.sessionId() == mySessionId) {
      // Read the status of the request to handle the state update.
    }
}

// Registers the listener.
splitInstallManager.registerListener(listener)

...

splitInstallManager
    .startInstall(request)
    // When the platform accepts your request to download
    // an on demand module, it binds it to the following session ID.
    // You use this ID to track further status updates for the request.
    .addOnSuccessListener { sessionId -> mySessionId = sessionId }
    // You should also add the following listener to handle any errors
    // processing the request.
    .addOnFailureListener { exception ->
        // Handle request errors.
    }

// When your app no longer requires further updates, unregister the listener.
splitInstallManager.unregisterListener(listener)

Java

// Initializes a variable to later track the session ID for a given request.
int mySessionId = 0;

// Creates a listener for request status updates.
SplitInstallStateUpdatedListener listener = state -> {
    if (state.sessionId() == mySessionId) {
      // Read the status of the request to handle the state update.
    }
};

// Registers the listener.
splitInstallManager.registerListener(listener);

...

splitInstallManager
    .startInstall(request)
    // When the platform accepts your request to download
    // an on demand module, it binds it to the following session ID.
    // You use this ID to track further status updates for the request.
    .addOnSuccessListener(sessionId -> { mySessionId = sessionId; })
    // You should also add the following listener to handle any errors
    // processing the request.
    .addOnFailureListener(exception -> {
        // Handle request errors.
    });

// When your app no longer requires further updates, unregister the listener.
splitInstallManager.unregisterListener(listener);

अनुरोध से जुड़ी गड़बड़ियां ठीक करना

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

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

Kotlin

splitInstallManager
    .startInstall(request)
    .addOnFailureListener { exception ->
        when ((exception as SplitInstallException).errorCode) {
            SplitInstallErrorCode.NETWORK_ERROR -> {
                // Display a message that requests the user to establish a
                // network connection.
            }
            SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED -> checkForActiveDownloads()
            ...
        }
    }

fun checkForActiveDownloads() {
    splitInstallManager
        // Returns a SplitInstallSessionState object for each active session as a List.
        .sessionStates
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // Check for active sessions.
                for (state in task.result) {
                    if (state.status() == SplitInstallSessionStatus.DOWNLOADING) {
                        // Cancel the request, or request a deferred installation.
                    }
                }
            }
        }
}

Java

splitInstallManager
    .startInstall(request)
    .addOnFailureListener(exception -> {
        switch (((SplitInstallException) exception).getErrorCode()) {
            case SplitInstallErrorCode.NETWORK_ERROR:
                // Display a message that requests the user to establish a
                // network connection.
                break;
            case SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED:
                checkForActiveDownloads();
            ...
    });

void checkForActiveDownloads() {
    splitInstallManager
        // Returns a SplitInstallSessionState object for each active session as a List.
        .getSessionStates()
        .addOnCompleteListener( task -> {
            if (task.isSuccessful()) {
                // Check for active sessions.
                for (SplitInstallSessionState state : task.getResult()) {
                    if (state.status() == SplitInstallSessionStatus.DOWNLOADING) {
                        // Cancel the request, or request a deferred installation.
                    }
                }
            }
        });
}

यहां दी गई टेबल में, गड़बड़ी की उन स्थितियों के बारे में बताया गया है जिन्हें आपके ऐप्लिकेशन को मैनेज करना पड़ सकता है:

गड़बड़ी कोड ब्यौरा सुझाई गई कार्रवाई
ACTIVE_SESSIONS_LIMIT_EXCEEDED अनुरोध अस्वीकार कर दिया गया है, क्योंकि कम से कम एक मौजूदा अनुरोध, फ़िलहाल डाउनलोड हो रहा है. देखें कि क्या कोई अनुरोध अब भी डाउनलोड हो रहा है, जैसा कि ऊपर दिए गए उदाहरण में दिखाया गया है.
मोड उपलब्ध नहीं है Google Play, ऐप्लिकेशन, डिवाइस, और उपयोगकर्ता के Google Play खाते के मौजूदा वर्शन के आधार पर, अनुरोध किया गया मॉड्यूल नहीं ढूंढ पा रहा है. अगर उपयोगकर्ता के पास मॉड्यूल का ऐक्सेस नहीं है, तो उसे इसकी सूचना दें.
INVALID_REQUEST Google Play को अनुरोध मिल गया है, लेकिन यह अनुरोध मान्य नहीं है. पुष्टि करें कि अनुरोध में दी गई जानकारी पूरी और सही है.
SESSION_NOT_FOUND किसी सेशन आईडी के लिए सेशन नहीं मिला. अगर आपको किसी अनुरोध की स्थिति को उसके सेशन आईडी के हिसाब से मॉनिटर करना है, तो पक्का करें कि सेशन आईडी सही हो.
API_NOT_AVAILABLE आपके मौजूदा डिवाइस पर, Play की सुविधा डिलीवरी लाइब्रेरी काम नहीं करती. इसका मतलब है कि डिवाइस, मांग पर सुविधाओं को डाउनलोड और इंस्टॉल नहीं कर पा रहा है. Android 4.4 (एपीआई लेवल 20) या इससे पहले के वर्शन वाले डिवाइसों के लिए, आपको dist:fusing मेनिफ़ेस्ट प्रॉपर्टी का इस्तेमाल करके, इंस्टॉल के समय सुविधा वाले मॉड्यूल शामिल करने चाहिए. ज़्यादा जानने के लिए, सुविधा मॉड्यूल मेनिफ़ेस्ट के बारे में पढ़ें.
NETWORK_ERROR नेटवर्क की गड़बड़ी की वजह से अनुरोध पूरा नहीं हुआ. उपयोगकर्ता को नेटवर्क से कनेक्ट करने या किसी दूसरे नेटवर्क पर स्विच करने के लिए कहें.
ACCESS_DENIED ज़रूरी अनुमतियां न होने की वजह से, ऐप्लिकेशन अनुरोध को रजिस्टर नहीं कर पा रहा है. आम तौर पर, ऐसा तब होता है, जब ऐप्लिकेशन बैकग्राउंड में हो. ऐप्लिकेशन के फ़ोरग्राउंड में वापस आने पर अनुरोध करने की कोशिश करें.
INCOMPATIBLE_WITH_EXISTING_SESSION अनुरोध में एक या एक से ज़्यादा ऐसे मॉड्यूल शामिल हैं जिनका अनुरोध पहले ही किया जा चुका है, लेकिन वे अब तक इंस्टॉल नहीं किए गए हैं. नया अनुरोध करें. इसमें वे मॉड्यूल शामिल न करें जिनका अनुरोध आपके ऐप्लिकेशन ने पहले ही किया है. इसके अलावा, अनुरोध फिर से करने से पहले, उन सभी मॉड्यूल के इंस्टॉल होने का इंतज़ार करें जिनका अनुरोध किया गया है.

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

SERVICE_DIED अनुरोध को हैंडल करने वाली सेवा बंद हो गई है. अनुरोध फिर से करें.

आपके SplitInstallStateUpdatedListener को SplitInstallSessionState मिला है. इसमें गड़बड़ी का यह कोड, स्टेटस FAILED, और सेशन आईडी -1 है.

INSUFFICIENT_STORAGE फ़ीचर मॉड्यूल को इंस्टॉल करने के लिए, डिवाइस में ज़रूरत के मुताबिक स्टोरेज नहीं है. उपयोगकर्ता को सूचना दें कि इस सुविधा को इंस्टॉल करने के लिए, उसके डिवाइस में स्टोरेज कम है.
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR SplitCompat, सुविधा मॉड्यूल को लोड नहीं कर सका. ऐप्लिकेशन को अगली बार रीस्टार्ट करने के बाद, ये गड़बड़ियां अपने-आप ठीक हो जाएंगी.
PLAY_STORE_NOT_FOUND डिवाइस पर Play Store ऐप्लिकेशन इंस्टॉल नहीं है. उपयोगकर्ता को बताएं कि इस सुविधा को डाउनलोड करने के लिए, Play Store ऐप्लिकेशन ज़रूरी है.
APP_NOT_OWNED ऐप्लिकेशन को Google Play से इंस्टॉल नहीं किया गया है और इस सुविधा को डाउनलोड नहीं किया जा सकता. यह गड़बड़ी, सिर्फ़ बाद में इंस्टॉल किए जाने वाले ऐप्लिकेशन के लिए हो सकती है. अगर आपको उपयोगकर्ता को Google Play से ऐप्लिकेशन डाउनलोड कराना है, तो startInstall() का इस्तेमाल करें. इससे उपयोगकर्ता की पुष्टि की ज़रूरी जानकारी मिल सकती है.
INTERNAL_ERROR Play Store में कोई आंतरिक गड़बड़ी हुई. अनुरोध फिर से करें.

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

स्थिति के अपडेट मैनेज करना

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

Kotlin

override fun onStateUpdate(state : SplitInstallSessionState) {
    if (state.status() == SplitInstallSessionStatus.FAILED
        && state.errorCode() == SplitInstallErrorCode.SERVICE_DIED) {
       // Retry the request.
       return
    }
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            SplitInstallSessionStatus.DOWNLOADING -> {
              val totalBytes = state.totalBytesToDownload()
              val progress = state.bytesDownloaded()
              // Update progress bar.
            }
            SplitInstallSessionStatus.INSTALLED -> {

              // After a module is installed, you can start accessing its content or
              // fire an intent to start an activity in the installed module.
              // For other use cases, see access code and resources from installed modules.

              // If the request is an on demand module for an Android Instant App
              // running on Android 8.0 (API level 26) or higher, you need to
              // update the app context using the SplitInstallHelper API.
            }
        }
    }
}

Java

@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.status() == SplitInstallSessionStatus.FAILED
        && state.errorCode() == SplitInstallErrorCode.SERVICE_DIES) {
       // Retry the request.
       return;
    }
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            case SplitInstallSessionStatus.DOWNLOADING:
              int totalBytes = state.totalBytesToDownload();
              int progress = state.bytesDownloaded();
              // Update progress bar.
              break;

            case SplitInstallSessionStatus.INSTALLED:

              // After a module is installed, you can start accessing its content or
              // fire an intent to start an activity in the installed module.
              // For other use cases, see access code and resources from installed modules.

              // If the request is an on demand module for an Android Instant App
              // running on Android 8.0 (API level 26) or higher, you need to
              // update the app context using the SplitInstallHelper API.
        }
    }
}

इंस्टॉल करने के आपके अनुरोध की संभावित स्थितियों के बारे में नीचे दी गई टेबल में बताया गया है.

अनुरोध की स्थिति ब्यौरा सुझाई गई कार्रवाई
लंबित अनुरोध स्वीकार कर लिया गया है और डाउनलोड जल्द ही शुरू हो जाना चाहिए. डाउनलोड के बारे में उपयोगकर्ता को सुझाव/राय देने के लिए, यूज़र इंटरफ़ेस (यूआई) के कॉम्पोनेंट को शुरू करें. जैसे, प्रोग्रेस बार.
REQUIRES_USER_CONFIRMATION डाउनलोड करने के लिए, उपयोगकर्ता की पुष्टि ज़रूरी है. आम तौर पर, यह स्टेटस तब दिखता है, जब ऐप्लिकेशन को Google Play से इंस्टॉल नहीं किया गया हो. उपयोगकर्ता से Google Play से सुविधा डाउनलोड करने की पुष्टि करने का अनुरोध करें. ज़्यादा जानने के लिए, उपयोगकर्ता की पुष्टि करने के तरीके के बारे में बताने वाले सेक्शन पर जाएं.
डाउनलोड करना डाउनलोड किया जा रहा है. अगर डाउनलोड के लिए प्रोग्रेस बार दिया जाता है, तो यूज़र इंटरफ़ेस (यूआई) को अपडेट करने के लिए, SplitInstallSessionState.bytesDownloaded() और SplitInstallSessionState.totalBytesToDownload() तरीकों का इस्तेमाल करें. इस टेबल के ऊपर दिए गए कोड का सैंपल देखें.
डाउनलोड किए गए डिवाइस ने मॉड्यूल डाउनलोड कर लिया है, लेकिन इंस्टॉलेशन की प्रोसेस शुरू नहीं हुई है. डाउनलोड किए गए मॉड्यूल को ऐक्सेस करने और यह स्टेटस न देखने के लिए, ऐप्लिकेशन को SplitCompat को चालू करना चाहिए. सुविधा मॉड्यूल के कोड और संसाधनों को ऐक्सेस करने के लिए, यह ज़रूरी है.
इंस्टॉल हो रहा है फ़िलहाल, डिवाइस पर मॉड्यूल इंस्टॉल हो रहा है. प्रोग्रेस बार अपडेट करें. यह स्थिति आम तौर पर छोटी होती है.
इंस्टॉल किया गया मॉड्यूल, डिवाइस पर इंस्टॉल हो गया हो. मॉड्यूल में मौजूद कोड और संसाधन ऐक्सेस करें, ताकि उपयोगकर्ता के सफ़र को जारी रखा जा सके.

अगर मॉड्यूल, Android 8.0 (एपीआई लेवल 26) या इसके बाद के वर्शन पर चलने वाले Android Instant App के लिए है, तो आपको नए मॉड्यूल की मदद से ऐप्लिकेशन के कॉम्पोनेंट अपडेट करने के लिए, splitInstallHelper का इस्तेमाल करना होगा.

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

उपयोगकर्ता की पुष्टि पाएं

कुछ मामलों में, डाउनलोड करने के अनुरोध को पूरा करने से पहले, Google Play को उपयोगकर्ता की पुष्टि की ज़रूरत पड़ सकती है. उदाहरण के लिए, अगर Google Play ने आपका ऐप्लिकेशन इंस्टॉल नहीं किया है या मोबाइल डेटा पर बहुत ज़्यादा डाउनलोड करने की कोशिश की जा रही है. ऐसे मामलों में, अनुरोध की स्थिति REQUIRES_USER_CONFIRMATION के तौर पर दिखती है. साथ ही, डिवाइस में अनुरोध में दिए गए मॉड्यूल डाउनलोड और इंस्टॉल करने से पहले, आपके ऐप्लिकेशन को उपयोगकर्ता की पुष्टि करनी होगी. पुष्टि करने के लिए, आपका ऐप्लिकेशन उपयोगकर्ता से इस तरह अनुरोध करे:

Kotlin

override fun onSessionStateUpdate(state: SplitInstallSessionState) {
    if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
        // Displays a confirmation for the user to confirm the request.
        splitInstallManager.startConfirmationDialogForResult(
          state,
          // an activity result launcher registered via registerForActivityResult
          activityResultLauncher)
    }
    ...
 }

Java

@Override void onSessionStateUpdate(SplitInstallSessionState state) {
    if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
        // Displays a confirmation for the user to confirm the request.
        splitInstallManager.startConfirmationDialogForResult(
          state,
          // an activity result launcher registered via registerForActivityResult
          activityResultLauncher);
    }
    ...
 }

आपके पास पहले से मौजूद ActivityResultContracts.StartIntentSenderForResult कॉन्ट्रैक्ट का इस्तेमाल करके, गतिविधि के नतीजे दिखाने वाले लॉन्चर को रजिस्टर करने का विकल्प है. Activity रिज़ल्ट के एपीआई देखें.

उपयोगकर्ता के जवाब के आधार पर, अनुरोध की स्थिति अपडेट की जाती है:

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

उपयोगकर्ता के जवाब के साथ कॉलबैक पाने के लिए, यहां दिखाए गए तरीके से ActivityResultCallback को बदला जा सकता है.

Kotlin

registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult -> {
        // Handle the user's decision. For example, if the user selects "Cancel",
        // you may want to disable certain functionality that depends on the module.
    }
}

Java

registerForActivityResult(
    new ActivityResultContracts.StartIntentSenderForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            // Handle the user's decision. For example, if the user selects "Cancel",
            // you may want to disable certain functionality that depends on the module.
        }
    });

इंस्टॉल करने का अनुरोध रद्द करना

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

Kotlin

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId)

Java

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId);

मॉड्यूल ऐक्सेस करना

डाउनलोड किए गए मॉड्यूल से कोड और रिसॉर्स ऐक्सेस करने के लिए, आपको अपने ऐप्लिकेशन और ऐप्लिकेशन में डाउनलोड किए जाने वाले फ़ीचर मॉड्यूल में मौजूद हर गतिविधि के लिए, SplitCompat Library को चालू करना होगा.

हालांकि, आपको ध्यान रखना चाहिए कि मॉड्यूल डाउनलोड करने के बाद, प्लैटफ़ॉर्म पर कुछ समय (कुछ दिनों में, कुछ मामलों में) के लिए, मॉड्यूल का कॉन्टेंट ऐक्सेस करने पर ये पाबंदियां होती हैं:

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

SplitCompat को चालू करना

आपका ऐप्लिकेशन, डाउनलोड किए गए मॉड्यूल से कोड और रिसॉर्स को ऐक्सेस कर सके, इसके लिए आपको नीचे दिए गए सेक्शन में बताए गए तरीकों में से किसी एक का इस्तेमाल करके, SplitCompat चालू करना होगा.

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

मेनिफ़ेस्ट में SplitCompatApplication का एलान करना

SplitCompat को चालू करने का सबसे आसान तरीका यह है कि आप अपने ऐप्लिकेशन के मेनिफ़ेस्ट में, SplitCompatApplication को Application सबक्लास के तौर पर एलान करें. इसके लिए, यहां दिया गया तरीका अपनाएं:

<application
    ...
    android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>

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

रनटाइम के दौरान SplitCompat को शुरू करना

रनटाइम के दौरान, कुछ खास गतिविधियों या सेवाओं में भी SplitCompat को चालू किया जा सकता है. सुविधा वाले मॉड्यूल में शामिल गतिविधियों को लॉन्च करने के लिए, SplitCompat को इस तरह चालू करना ज़रूरी है. इसके लिए, attachBaseContext को बदलें. इसके लिए, नीचे दिया गया तरीका अपनाएं.

अगर आपके पास कस्टम Application क्लास है, तो अपने ऐप्लिकेशन के लिए SplitCompat को चालू करने के लिए, उसे SplitCompatApplication के बजाय, SplitCompatApplication से एक्सटेंड करें. इसके लिए, नीचे दिया गया तरीका अपनाएं:

Kotlin

class MyApplication : SplitCompatApplication() {
    ...
}

Java

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication, SplitCompat.install(Context applicationContext) को शामिल करने के लिए, ContextWrapper.attachBaseContext() को बदल देता है. अगर आपको अपनी Application क्लास को SplitCompatApplication तक नहीं बढ़ाना है, तो attachBaseContext() तरीके को मैन्युअल तरीके से बदला जा सकता है. इसके लिए, यह तरीका अपनाएं:

Kotlin

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this);
}

अगर आपका ऑन डिमांड मॉड्यूल, इंस्टॉल किए गए ऐप्लिकेशन और इंस्टैंट ऐप्लिकेशन, दोनों के साथ काम करता है, तो SplitCompat को शर्तों के साथ इस तरह से चालू किया जा सकता है:

Kotlin

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    if (!InstantApps.isInstantApp(this)) {
        SplitCompat.install(this)
    }
}

Java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    if (!InstantApps.isInstantApp(this)) {
        SplitCompat.install(this);
    }
}

मॉड्यूल गतिविधियों के लिए SplitCompat चालू करें

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

Kotlin

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    // Emulates installation of on demand modules using SplitCompat.
    SplitCompat.installActivity(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of on demand modules using SplitCompat.
    SplitCompat.installActivity(this);
}

फ़ीचर मॉड्यूल में तय किए गए कॉम्पोनेंट ऐक्सेस करना

सुविधा वाले मॉड्यूल में बताई गई गतिविधि शुरू करना

SplitCompat को चालू करने के बाद, startActivity() का इस्तेमाल करके, सुविधा वाले मॉड्यूल में तय की गई गतिविधियां लॉन्च की जा सकती हैं.

Kotlin

startActivity(Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...))

Java

startActivity(new Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...));

setClassName का पहला पैरामीटर, ऐप्लिकेशन के पैकेज का नाम है और दूसरा पैरामीटर, ऐक्टिविटी की पूरी क्लास का नाम है.

अगर आपने मांग पर डाउनलोड किए गए सुविधा वाले मॉड्यूल में कोई गतिविधि की है, तो आपको गतिविधि में SplitCompat को चालू करना होगा.

सुविधा मॉड्यूल में बताई गई सेवा शुरू करना

SplitCompat को चालू करने के बाद startService() का इस्तेमाल करके, फ़ीचर मॉड्यूल में बताई गई सेवाओं को लॉन्च किया जा सकता है.

Kotlin

startService(Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...))

Java

startService(new Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...));

सुविधा वाले मॉड्यूल में तय किए गए कॉम्पोनेंट को एक्सपोर्ट करना

आपको वैकल्पिक मॉड्यूल में, एक्सपोर्ट किए गए Android कॉम्पोनेंट शामिल नहीं करने चाहिए.

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

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

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

इंस्टॉल किए गए मॉड्यूल से कोड और संसाधन ऐक्सेस करें

अगर आपने अपने ऐप्लिकेशन के मुख्य कॉन्टेक्स्ट और सुविधा वाले मॉड्यूल में मौजूद गतिविधियों के लिए, SplitCompat को चालू किया है, तो वैकल्पिक मॉड्यूल इंस्टॉल होने के बाद, सुविधा वाले मॉड्यूल के कोड और संसाधनों का इस्तेमाल, मुख्य APK के हिस्से के तौर पर किया जा सकता है.

किसी दूसरे मॉड्यूल से ऐक्सेस कोड

किसी मॉड्यूल से बुनियादी कोड ऐक्सेस करना

आपके बेस मॉड्यूल में मौजूद कोड का इस्तेमाल, दूसरे मॉड्यूल सीधे तौर पर कर सकते हैं. इसके लिए, आपको कुछ भी खास करने की ज़रूरत नहीं है. बस अपनी ज़रूरत के हिसाब से क्लास इंपोर्ट करें और उनका इस्तेमाल करें.

किसी दूसरे मॉड्यूल से मॉड्यूल कोड ऐक्सेस करना

किसी मॉड्यूल में मौजूद ऑब्जेक्ट या क्लास को, किसी दूसरे मॉड्यूल से सीधे तौर पर स्टैटिक तौर पर ऐक्सेस नहीं किया जा सकता. हालांकि, रिफ़्लेक्शन का इस्तेमाल करके, उसे किसी दूसरे मॉड्यूल से ऐक्सेस किया जा सकता है.

आपको इस बात का ध्यान रखना चाहिए कि ऐसा कितनी बार होता है, क्योंकि रीफ़्लेक्शन की वजह से परफ़ॉर्मेंस पर असर पड़ता है. मुश्किल इस्तेमाल के मामलों के लिए, Dagger 2 जैसे डिपेंडेंसी इंजेक्शन फ़्रेमवर्क का इस्तेमाल करें. इससे यह पक्का किया जा सकेगा कि हर ऐप्लिकेशन में एक ही रिफ़्लेक्शन कॉल होगा.

ऑब्जेक्ट बनाने के बाद, उससे इंटरैक्ट करना आसान बनाने के लिए, हमारा सुझाव है कि आप बेस मॉड्यूल में इंटरफ़ेस तय करें और उसे सुविधा मॉड्यूल में लागू करें. उदाहरण के लिए:

Kotlin

// In the base module
interface MyInterface {
  fun hello(): String
}

// In the feature module
object MyInterfaceImpl : MyInterface {
  override fun hello() = "Hello"
}

// In the base module, where we want to access the feature module code
val stringFromModule = (Class.forName("com.package.module.MyInterfaceImpl")
    .kotlin.objectInstance as MyInterface).hello();

Java

// In the base module
public interface MyInterface {
  String hello();
}

// In the feature module
public class MyInterfaceImpl implements MyInterface {
  @Override
  public String hello() {
    return "Hello";
  }
}

// In the base module, where we want to access the feature module code
String stringFromModule =
   ((MyInterface) Class.forName("com.package.module.MyInterfaceImpl").getConstructor().newInstance()).hello();

किसी दूसरे मॉड्यूल से संसाधन और एसेट ऐक्सेस करना

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

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

मांग पर डिलीवरी की सुविधा का इस्तेमाल करके, किसी ऐप्लिकेशन में नेटिव कोड लोड करना

हमारा सुझाव है कि सुविधा वाले मॉड्यूल की ऑन-डिमांड डिलीवरी का इस्तेमाल करते समय, अपनी सभी नेटिव लाइब्रेरी लोड करने के लिए ReLinker का इस्तेमाल करें. सुविधा मॉड्यूल इंस्टॉल होने के बाद, ReLinker नेटिव लाइब्रेरी लोड होने में आ रही समस्या को ठीक करता है. Android JNI के बारे में सलाह में जाकर, ReLinker के बारे में ज़्यादा जानें.

वैकल्पिक मॉड्यूल से नेटिव कोड लोड करें

स्प्लिट इंस्टॉल होने के बाद, हमारा सुझाव है कि आप ReLinker की मदद से उसका नेटिव कोड लोड करें. इंस्टैंट ऐप्लिकेशन के लिए, आपको इस खास तरीके का इस्तेमाल करना चाहिए.

अगर अपने नेटिव कोड को लोड करने के लिए System.loadLibrary() का इस्तेमाल किया जा रहा है और आपकी नेटिव लाइब्रेरी, मॉड्यूल में मौजूद किसी दूसरी लाइब्रेरी पर निर्भर है, तो आपको पहले उस दूसरी लाइब्रेरी को मैन्युअल तरीके से लोड करना होगा. अगर ReLinker का इस्तेमाल किया जा रहा है, तो इसके लिए Relinker.recursively().loadLibrary() का इस्तेमाल किया जा सकता है.

अगर किसी वैकल्पिक मॉड्यूल में बताई गई लाइब्रेरी को लोड करने के लिए, नेटिव कोड में dlopen() का इस्तेमाल किया जा रहा है, तो यह रिलेटिव लाइब्रेरी पाथ के साथ काम नहीं करेगा. सबसे अच्छा तरीका यह है कि ClassLoader.findLibrary() के ज़रिए, Java कोड से लाइब्रेरी का पूरा पाथ पाएं. इसके बाद, dlopen() कॉल में इसका इस्तेमाल करें. नेटिव कोड डालने से पहले ऐसा करें या Java में अपने नेटिव कोड से JNI कॉल का इस्तेमाल करें.

इंस्टॉल किए गए Android Instant Apps ऐक्सेस करना

जब Android Instant App मॉड्यूल INSTALLED के तौर पर रिपोर्ट करता है, तो रीफ़्रेश किए गए ऐप्लिकेशन कॉन्टेक्स्ट का इस्तेमाल करके, उसका कोड और संसाधन ऐक्सेस किए जा सकते हैं. किसी मॉड्यूल को इंस्टॉल करने से पहले आपका ऐप्लिकेशन जो कॉन्टेक्स्ट बनाता है उसमें नए मॉड्यूल का कॉन्टेंट शामिल नहीं होता. उदाहरण के लिए, वह कॉन्टेक्स्ट जो पहले से ही किसी वैरिएबल में सेव होता है. हालांकि, नया कॉन्टेक्स्ट ऐसा करता है. उदाहरण के लिए, इसे createPackageContext का इस्तेमाल करके पाया जा सकता है.

Kotlin

// Generate a new context as soon as a request for a new module
// reports as INSTALLED.
override fun onStateUpdate(state: SplitInstallSessionState ) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            ...
            SplitInstallSessionStatus.INSTALLED -> {
                val newContext = context.createPackageContext(context.packageName, 0)
                // If you use AssetManager to access your app’s raw asset files, you’ll need
                // to generate a new AssetManager instance from the updated context.
                val am = newContext.assets
            }
        }
    }
}

Java

// Generate a new context as soon as a request for a new module
// reports as INSTALLED.
@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            ...
            case SplitInstallSessionStatus.INSTALLED:
                Context newContext = context.createPackageContext(context.getPackageName(), 0);
                // If you use AssetManager to access your app’s raw asset files, you’ll need
                // to generate a new AssetManager instance from the updated context.
                AssetManager am = newContext.getAssets();
        }
    }
}

Android 8.0 और इसके बाद के वर्शन पर Android Instant Apps

Android 8.0 (एपीआई लेवल 26) और उसके बाद के वर्शन पर, Android इंस्टैंट ऐप्लिकेशन के लिए ऑन डिमांड मॉड्यूल का अनुरोध करने पर, इंस्टॉल करने के अनुरोध की रिपोर्ट INSTALLED के तौर पर दिखने के बाद, आपको SplitInstallHelper.updateAppInfo(Context context) को कॉल करके, ऐप्लिकेशन को नए मॉड्यूल के कॉन्टेक्स्ट के साथ अपडेट करना होगा. ऐसा न करने पर, ऐप्लिकेशन को मॉड्यूल के कोड और संसाधनों के बारे में जानकारी नहीं होगी. ऐप्लिकेशन का मेटाडेटा अपडेट करने के बाद, अगले मुख्य थ्रेड इवेंट के दौरान मॉड्यूल का कॉन्टेंट लोड करने के लिए, नए Handler का इस्तेमाल करें, जैसा कि यहां दिखाया गया है:

Kotlin

override fun onStateUpdate(state: SplitInstallSessionState ) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            ...
            SplitInstallSessionStatus.INSTALLED -> {
                // You need to perform the following only for Android Instant Apps
                // running on Android 8.0 (API level 26) and higher.
                if (BuildCompat.isAtLeastO()) {
                    // Updates the app’s context with the code and resources of the
                    // installed module.
                    SplitInstallHelper.updateAppInfo(context)
                    Handler().post {
                        // Loads contents from the module using AssetManager
                        val am = context.assets
                        ...
                    }
                }
            }
        }
    }
}

Java

@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            ...
            case SplitInstallSessionStatus.INSTALLED:
            // You need to perform the following only for Android Instant Apps
            // running on Android 8.0 (API level 26) and higher.
            if (BuildCompat.isAtLeastO()) {
                // Updates the app’s context with the code and resources of the
                // installed module.
                SplitInstallHelper.updateAppInfo(context);
                new Handler().post(new Runnable() {
                    @Override public void run() {
                        // Loads contents from the module using AssetManager
                        AssetManager am = context.getAssets();
                        ...
                    }
                });
            }
        }
    }
}

C/C++ लाइब्रेरी लोड करना

अगर आपको किसी ऐसे मॉड्यूल से C/C++ लाइब्रेरी लोड करनी है जिसे डिवाइस पर पहले से ही इंस्टैंट ऐप्लिकेशन में डाउनलोड किया जा चुका है, तो नीचे दिए गए तरीके के मुताबिक SplitInstallHelper.loadLibrary(Context context, String libName) का इस्तेमाल करें:

Kotlin

override fun onStateUpdate(state: SplitInstallSessionState) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            SplitInstallSessionStatus.INSTALLED -> {
                // Updates the app’s context as soon as a module is installed.
                val newContext = context.createPackageContext(context.packageName, 0)
                // To load C/C++ libraries from an installed module, use the following API
                // instead of System.load().
                SplitInstallHelper.loadLibrary(newContext, my-cpp-lib)
                ...
            }
        }
    }
}

Java

public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            case SplitInstallSessionStatus.INSTALLED:
                // Updates the app’s context as soon as a module is installed.
                Context newContext = context.createPackageContext(context.getPackageName(), 0);
                // To load C/C++ libraries from an installed module, use the following API
                // instead of System.load().
                SplitInstallHelper.loadLibrary(newContext, my-cpp-lib);
                ...
        }
    }
}

सीमाएं

  • किसी ऐसी गतिविधि में Android वेबव्यू का इस्तेमाल नहीं किया जा सकता जो वैकल्पिक मॉड्यूल से संसाधन या एसेट ऐक्सेस करता है. ऐसा इसलिए होता है, क्योंकि Android एपीआई लेवल 28 और उससे पहले के वर्शन पर, WebView और SplitCompat के बीच काम करने में समस्या आती है.
  • Android ApplicationInfo ऑब्जेक्ट, उनके कॉन्टेंट या उन ऑब्जेक्ट को कैश मेमोरी में सेव नहीं किया जा सकता जिनमें ये ऑब्जेक्ट शामिल हैं. आपको इन ऑब्जेक्ट को ज़रूरत के हिसाब से, ऐप्लिकेशन के संदर्भ से फ़ेच करना चाहिए. ऐसे ऑब्जेक्ट को कैश मेमोरी में सेव करने से, किसी सुविधा वाले मॉड्यूल को इंस्टॉल करते समय ऐप्लिकेशन क्रैश हो सकता है.

इंस्टॉल किए गए मॉड्यूल मैनेज करना

यह देखने के लिए कि डिवाइस पर फ़िलहाल कौनसे सुविधा वाले मॉड्यूल इंस्टॉल हैं, SplitInstallManager.getInstalledModules() को कॉल करें. इससे, इंस्टॉल किए गए मॉड्यूल के नामों का Set<String> दिखेगा, जैसा कि नीचे दिखाया गया है.

Kotlin

val installedModules: Set<String> = splitInstallManager.installedModules

Java

Set<String> installedModules = splitInstallManager.getInstalledModules();

मॉड्यूल अनइंस्टॉल करना

डिवाइस पर मॉड्यूल अनइंस्टॉल करने का अनुरोध करने के लिए, SplitInstallManager.deferredUninstall(List<String> moduleNames) को नीचे दिखाए गए तरीके से लागू करें.

Kotlin

// Specifies two feature modules for deferred uninstall.
splitInstallManager.deferredUninstall(listOf("pictureMessages", "promotionalFilters"))

Java

// Specifies two feature modules for deferred uninstall.
splitInstallManager.deferredUninstall(Arrays.asList("pictureMessages", "promotionalFilters"));

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

भाषा के अन्य संसाधनों को डाउनलोड करें

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

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

Kotlin

// Captures the user’s preferred language and persists it
// through the app’s SharedPreferences.
sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply()
...

// Creates a request to download and install additional language resources.
val request = SplitInstallRequest.newBuilder()
        // Uses the addLanguage() method to include French language resources in the request.
        // Note that country codes are ignored. That is, if your app
        // includes resources for “fr-FR” and “fr-CA”, resources for both
        // country codes are downloaded when requesting resources for "fr".
        .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
        .build()

// Submits the request to install the additional language resources.
splitInstallManager.startInstall(request)

Java

// Captures the user’s preferred language and persists it
// through the app’s SharedPreferences.
sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply();
...

// Creates a request to download and install additional language resources.
SplitInstallRequest request =
    SplitInstallRequest.newBuilder()
        // Uses the addLanguage() method to include French language resources in the request.
        // Note that country codes are ignored. That is, if your app
        // includes resources for “fr-FR” and “fr-CA”, resources for both
        // country codes are downloaded when requesting resources for "fr".
        .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
        .build();

// Submits the request to install the additional language resources.
splitInstallManager.startInstall(request);

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

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

Kotlin

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

Java

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

भाषा के लिए डाउनलोड किए गए संसाधनों को ऐक्सेस करना

डाउनलोड की गई भाषा के संसाधनों का ऐक्सेस पाने के लिए, आपके ऐप्लिकेशन को हर उस गतिविधि के attachBaseContext() तरीके में SplitCompat.installActivity() तरीका चलाना होगा जिसके लिए उन संसाधनों का ऐक्सेस ज़रूरी है. इसका तरीका यहां बताया गया है.

Kotlin

override fun attachBaseContext(base: Context) {
  super.attachBaseContext(base)
  SplitCompat.installActivity(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
  super.attachBaseContext(base);
  SplitCompat.installActivity(this);
}

आपको जिन गतिविधियों के लिए, ऐप्लिकेशन में डाउनलोड किए गए भाषा संसाधनों का इस्तेमाल करना है उनके लिए, बेस कॉन्टेक्स्ट अपडेट करें और Configuration के ज़रिए नई स्थानीय भाषा सेट करें:

Kotlin

override fun attachBaseContext(base: Context) {
  val configuration = Configuration()
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
  val context = base.createConfigurationContext(configuration)
  super.attachBaseContext(context)
  SplitCompat.install(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
  Configuration configuration = new Configuration();
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
  Context context = base.createConfigurationContext(configuration);
  super.attachBaseContext(context);
  SplitCompat.install(this);
}

इन बदलावों को लागू करने के लिए, आपको नई भाषा के इंस्टॉल होने और इस्तेमाल के लिए तैयार होने के बाद, अपनी गतिविधि फिर से बनानी होगी. इसके लिए, Activity#recreate() वाला तरीका इस्तेमाल करें.

Kotlin

when (state.status()) {
  SplitInstallSessionStatus.INSTALLED -> {
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate()
  }
  ...
}

Java

switch (state.status()) {
  case SplitInstallSessionStatus.INSTALLED:
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate();
  ...
}

भाषा के अन्य संसाधनों को अनइंस्टॉल करना

फ़ीचर मॉड्यूल की तरह ही, अतिरिक्त संसाधनों को कभी भी अनइंस्टॉल किया जा सकता है. अनइंस्टॉल करने का अनुरोध करने से पहले, यह पता लगाएं कि फ़िलहाल कौनसी भाषाएं इंस्टॉल हैं. इसके लिए, यह तरीका अपनाएं.

Kotlin

val installedLanguages: Set<String> = splitInstallManager.installedLanguages

Java

Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();

इसके बाद, यह तय किया जा सकता है कि deferredLanguageUninstall() तरीके का इस्तेमाल करके कौनसी भाषाएं अनइंस्टॉल करनी हैं, जैसा कि यहां दिखाया गया है.

Kotlin

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

Java

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

मॉड्यूल इंस्टॉल करने की प्रोसेस की जांच करना

Play की सुविधा डिलीवरी लाइब्रेरी की मदद से, Play Store से कनेक्ट किए बिना अपने ऐप्लिकेशन की इन सुविधाओं की जांच की जा सकती है:

  • मॉड्यूल इंस्टॉल करने का अनुरोध करना और उन्हें मॉनिटर करना.
  • इंस्टॉल करने से जुड़ी गड़बड़ियां ठीक करना.
  • मॉड्यूल ऐक्सेस करने के लिए SplitCompat का इस्तेमाल करें.

इस पेज पर, टेस्टिंग के लिए इस्तेमाल किए जाने वाले डिवाइस पर, ऐप्लिकेशन के अलग-अलग APKs को डिप्लॉय करने का तरीका बताया गया है. इससे Play Feature Delivery, Play Store से मॉड्यूल का अनुरोध करने, उन्हें डाउनलोड करने, और इंस्टॉल करने के लिए, उन APKs का अपने-आप इस्तेमाल कर पाता है.

आपको अपने ऐप्लिकेशन के लॉजिक में कोई बदलाव करने की ज़रूरत नहीं है. हालांकि, आपको इन ज़रूरी शर्तों को पूरा करना होगा:

  • bundletool का नया वर्शन डाउनलोड और इंस्टॉल करें. आपको अपने ऐप्लिकेशन के बंडल से, इंस्टॉल किए जा सकने वाले APK का नया सेट बनाने के लिए bundletool की ज़रूरत होगी.

APK का सेट बनाना

अगर आपने अब तक ऐसा नहीं किया है, तो अपने ऐप्लिकेशन के अलग-अलग APK बनाएं. इसके लिए, यह तरीका अपनाएं:

  1. इनमें से किसी एक तरीके का इस्तेमाल करके, अपने ऐप्लिकेशन के लिए ऐप्लिकेशन बंडल बनाएं:
  2. सभी डिवाइस कॉन्फ़िगरेशन के लिए, एपीके का एक सेट जनरेट करने के लिए, bundletool का इस्तेमाल करें. इसके लिए, यह कमांड इस्तेमाल करें:

    bundletool build-apks --local-testing
      --bundle my_app.aab
      --output my_app.apks
    

--local-testing फ़्लैग में आपके APK के मेनिफ़ेस्ट में मौजूद मेटाडेटा शामिल होता है. इससे Play Feature Delivery लाइब्रेरी को पता चलता है कि Play Store से कनेक्ट किए बिना, सुविधा वाले मॉड्यूल इंस्टॉल करने के लिए, अलग-अलग हिस्सों में बंटे APK का इस्तेमाल कैसे करना है.

अपने ऐप्लिकेशन को डिवाइस पर डिप्लॉय करना

--local-testing फ़्लैग का इस्तेमाल करके APKs का सेट बनाने के बाद, अपने ऐप्लिकेशन का बेस वर्शन इंस्टॉल करने और अन्य APKs को अपने डिवाइस के लोकल स्टोरेज में ट्रांसफ़र करने के लिए, bundletool का इस्तेमाल करें. इन दोनों कार्रवाइयों को करने के लिए, यह कमांड इस्तेमाल करें:

bundletool install-apks --apks my_app.apks

अब, जब ऐप्लिकेशन चालू किया जाता है और फ़ीचर मॉड्यूल को डाउनलोड और इंस्टॉल करने के लिए यूज़र फ़्लो को पूरा किया जाता है, तो Play Feature Delivery Library उन APK का इस्तेमाल करती है जिन्हें bundletool डिवाइस के लोकल स्टोरेज में ट्रांसफ़र किया जाता है.

नेटवर्क की गड़बड़ी को सिम्युलेट करना

Play Store से मॉड्यूल इंस्टॉल करने की प्रोसेस को सिम्युलेट करने के लिए, Play Feature Delivery लाइब्रेरी में, मॉड्यूल का अनुरोध करने के लिए SplitInstallManager के अलावा एक विकल्प का इस्तेमाल FakeSplitInstallManager किया जाता है. APK का सेट बनाने और उसे टेस्ट डिवाइस पर डिप्लॉय करने के लिए, --local-testing फ़्लैग के साथ bundletool का इस्तेमाल करने पर, इसमें मेटाडेटा शामिल होता है. यह मेटाडेटा, Play की सुविधा डिलीवरी लाइब्रेरी को निर्देश देता है कि वह आपके ऐप्लिकेशन के एपीआई कॉल को अपने-आप स्विच कर दे, ताकि SplitInstallManager के बजाय FakeSplitInstallManager को ट्रिगर किया जा सके.

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

Kotlin

// Creates an instance of FakeSplitInstallManager with the app's context.
val fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context)
// Tells Play Feature Delivery Library to force the next module request to
// result in a network error.
fakeSplitInstallManager.setShouldNetworkError(true)

Java

// Creates an instance of FakeSplitInstallManager with the app's context.
FakeSplitInstallManager fakeSplitInstallManager =
    FakeSplitInstallManagerFactory.create(context);
// Tells Play Feature Delivery Library to force the next module request to
// result in a network error.
fakeSplitInstallManager.setShouldNetworkError(true);