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

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

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

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

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

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

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

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

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

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

    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) और इससे पहले के वर्शन वाले डिवाइसों के लिए उपलब्ध कराना है, तो फ़्यूज़िंग के बगल में मौजूद बॉक्स को चुनें. साथ ही, इसे मल्टी-APK में शामिल करें. इसका मतलब है कि इस मॉड्यूल के लिए, मांग के हिसाब से काम करने की सुविधा चालू की जा सकती है. साथ ही, फ़्यूज़ करने की सुविधा को बंद किया जा सकता है, ताकि इसे उन डिवाइसों से हटाया जा सके जो split APKs को डाउनलोड और इंस्टॉल नहीं कर सकते. Android Studio, आपकी पसंद के हिसाब से मॉड्यूल के मेनिफ़ेस्ट में ये चीज़ें शामिल करता है:

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

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

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

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

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

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

जब आपके ऐप्लिकेशन को किसी फ़ीचर मॉड्यूल का इस्तेमाल करना होता है, तो वह फ़ोरग्राउंड में रहते हुए, 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 लाइब्रेरी, “फ़ायर-ऐंड-फ़ॉरगेट” रणनीति का इस्तेमाल करती है. इसका मतलब है कि यह प्लैटफ़ॉर्म पर मॉड्यूल को डाउनलोड करने का अनुरोध भेजता है, लेकिन यह मॉनिटर नहीं करता कि मॉड्यूल इंस्टॉल हुआ या नहीं. इंस्टॉल करने के बाद, उपयोगकर्ता अनुभव को बेहतर बनाने या गड़बड़ियों को ठीक करने के लिए, पक्का करें कि आपने अनुरोध की स्थिति पर नज़र रखी हो.

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

मॉड्यूल के कोड और संसाधनों को ऐक्सेस करने के लिए, आपके ऐप्लिकेशन को SplitCompat चालू करना होगा. ध्यान दें कि Android Instant Apps के लिए, 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() टास्क से स्टेटस अपडेट सुनने होंगे. इंस्टॉल करने के अनुरोध के बारे में अपडेट पाने से पहले, लिसनर को रजिस्टर करें और अनुरोध के लिए सेशन आईडी पाएं. इसके बारे में यहां बताया गया है.

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

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

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

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

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 का इस्तेमाल करके, ऐप्लिकेशन के कॉम्पोनेंट को नए मॉड्यूल के साथ अपडेट करना होगा.

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

उपयोगकर्ता की सहमति लेना

कुछ मामलों में, डाउनलोड करने का अनुरोध पूरा करने से पहले, 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 Result API देखें.

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

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

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

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

SplitCompat चालू करना

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

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

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

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

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

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

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

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

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

Kotlin

class MyApplication : SplitCompatApplication() {
    ...
}

Java

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication, ContextWrapper.attachBaseContext() को ओवरराइड करता है, ताकि SplitCompat.install(Context applicationContext) को शामिल किया जा सके. अगर आपको अपनी 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 जेएनआई से जुड़ी सलाह में, ReLinker के बारे में ज़्यादा जानकारी मिल सकती है.

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

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

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

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

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

Android Instant Apps मॉड्यूल के 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 Instant Apps के लिए मांग पर उपलब्ध मॉड्यूल का अनुरोध करते समय, इंस्टॉल करने का अनुरोध 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 WebView का इस्तेमाल ऐसी गतिविधि में नहीं किया जा सकता जो किसी वैकल्पिक मॉड्यूल से संसाधनों या ऐसेट को ऐक्सेस करती है. ऐसा इसलिए होता है, क्योंकि 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 Feature Delivery लाइब्रेरी का इस्तेमाल करके, ज़रूरत के हिसाब से उन्हें डाउनलोड किया जा सकता है. उदाहरण के लिए, ऐप्लिकेशन में भाषा चुनने की सुविधा लागू करने के लिए. यह प्रोसेस, फ़ीचर मॉड्यूल को डाउनलोड करने की प्रोसेस जैसी ही है, जैसा कि यहां दिखाया गया है.

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 Feature Delivery लाइब्रेरी की मदद से, Play Store से कनेक्ट किए बिना, अपने ऐप्लिकेशन की इन सुविधाओं को स्थानीय तौर पर टेस्ट किया जा सकता है:

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

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

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

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

APK का सेट बनाना

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

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

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

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

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

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

bundletool install-apks --apks my_app.apks

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

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

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