चेतावनी: अगस्त 2021 से, सभी नए ऐप्लिकेशन को ऐप्लिकेशन बंडल के तौर पर पब्लिश करना ज़रूरी है. अगर आपको Google Play पर अपना ऐप्लिकेशन पब्लिश करना है, तो Android ऐप्लिकेशन बंडल बनाएं और उसे अपलोड करें. ऐसा करने पर, Google Play हर उपयोगकर्ता के डिवाइस कॉन्फ़िगरेशन के हिसाब से ऑप्टिमाइज़ किए गए APK अपने-आप जनरेट करता है और उन्हें उपलब्ध कराता है. इसलिए, उपयोगकर्ता सिर्फ़ उस कोड और संसाधनों को डाउनलोड करते हैं जिनकी उन्हें आपका ऐप्लिकेशन चलाने के लिए ज़रूरत होती है. अगर आपको किसी ऐसे स्टोर पर ऐप्लिकेशन पब्लिश करना है जो AAB फ़ॉर्मैट के साथ काम नहीं करता है, तो एक से ज़्यादा APK पब्लिश करना फ़ायदेमंद होता है. ऐसे में, आपको हर APK को खुद ही बनाना, साइन करना, और मैनेज करना होगा.
हालांकि, जब भी हो सके, अपने सभी टारगेट डिवाइसों के लिए एक ही APK बनाना बेहतर होता है. हालांकि, ऐसा करने पर APK का साइज़ बहुत बड़ा हो सकता है. ऐसा इसलिए होता है, क्योंकि फ़ाइलें कई ऐप्लिकेशन बाइनरी इंटरफ़ेस (एबीआई) के साथ काम करती हैं. अपने APK का साइज़ कम करने का एक तरीका यह है कि एक से ज़्यादा APK बनाएं. इनमें खास एबीआइ के लिए फ़ाइलें शामिल होती हैं.
Gradle, अलग-अलग APK बना सकता है. इनमें सिर्फ़ कोड और हर एबीआई के लिए खास संसाधन होते हैं. इस पेज पर, एक से ज़्यादा APK जनरेट करने के लिए, अपने बिल्ड को कॉन्फ़िगर करने का तरीका बताया गया है. अगर आपको अपने ऐप्लिकेशन के ऐसे अलग-अलग वर्शन बनाने हैं जो एबीआई पर आधारित नहीं हैं, तो इसके बजाय बिल्ड वैरिएंट का इस्तेमाल करें.
एक से ज़्यादा APK के लिए, बिल्ड कॉन्फ़िगर करना
एक से ज़्यादा APK के लिए अपनी बिल्ड को कॉन्फ़िगर करने के लिए, मॉड्यूल-लेवल की build.gradle फ़ाइल में
splits ब्लॉक जोड़ें. splits ब्लॉक में, abi ब्लॉक दें. इससे यह तय किया जाता है कि Gradle, हर ABI के हिसाब से APK कैसे जनरेट करेगा.
एबीआई के लिए एक से ज़्यादा APK कॉन्फ़िगर करना
अलग-अलग ABI के लिए अलग-अलग APK बनाने के लिए, अपने abi ब्लॉक में abi ब्लॉक जोड़ें.splits अपने abi ब्लॉक में, पसंद के एबीआई की सूची दें.
हर ABI के लिए एक से ज़्यादा एपीके कॉन्फ़िगर करने के लिए, Gradle DSL के इन विकल्पों का इस्तेमाल किया जाता है:
-
Groovy के लिए
enableया Kotlin स्क्रिप्ट के लिएisEnable - इस एलिमेंट को
trueपर सेट करने पर, Gradle आपके तय किए गए एबीआइ के आधार पर कई APK जनरेट करता है. डिफ़ॉल्ट वैल्यूfalseहै. -
exclude -
इससे, कॉमा लगाकर अलग किए गए उन एबीआई की सूची तय की जाती है जिनके लिए आपको Gradle से अलग-अलग APK जनरेट नहीं कराने हैं. अगर आपको ज़्यादातर एबीआई के लिए APK जनरेट करने हैं, लेकिन आपको कुछ ऐसे एबीआई शामिल नहीं करने हैं जिन्हें आपका ऐप्लिकेशन सपोर्ट नहीं करता, तो
excludeका इस्तेमाल करें. -
reset() -
यह एबीआई की डिफ़ॉल्ट सूची को मिटाता है. इसका इस्तेमाल सिर्फ़ तब करें, जब आपको
includeएलिमेंट के साथ जोड़कर, वे एबीआइ तय करने हों जिन्हें आपको जोड़ना है.यहां दिए गए स्निपेट में, एबीआई की सूची को सिर्फ़
x86औरx86_64पर सेट किया गया है. इसके लिए,reset()को कॉल करके सूची को मिटाया गया है. इसके बाद,includeका इस्तेमाल किया गया है:reset() // Clears the default list from all ABIs to no ABIs. include "x86", "x86_64" // Specifies the two ABIs we want to generate APKs for.
-
include -
इसमें कॉमा लगाकर अलग किए गए उन एबीआई की सूची दी जाती है जिनके लिए आपको Gradle से APK जनरेट करने हैं. एबीआई की सटीक सूची तय करने के लिए, इसका इस्तेमाल सिर्फ़
reset()के साथ करें. -
Groovy के लिए
universalApkया Kotlin स्क्रिप्ट के लिएisUniversalApk -
अगर
true, तो Gradle, हर एबीआई के हिसाब से APK जनरेट करने के साथ-साथ, एक यूनिवर्सल APK भी जनरेट करता है. यूनिवर्सल APK में, एक ही APK में सभी एबीआइ के लिए कोड और संसाधन शामिल होते हैं. डिफ़ॉल्ट वैल्यूfalseहै.
यहां दिए गए उदाहरण में, हर एबीआई के लिए एक अलग APK जनरेट किया गया है: x86
और x86_64. इसके लिए, reset() का इस्तेमाल करके एबीआई की खाली सूची शुरू की जाती है. इसके बाद, include का इस्तेमाल करके एबीआई की ऐसी सूची बनाई जाती है जिसमें हर एबीआई को एक APK मिलता है.
Groovy
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. enable true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include "x86", "x86_64" // Specifies that you don't want to also generate a universal APK that includes all ABIs. universalApk false } } }
Kotlin
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. isEnable = true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include("x86", "x86_64") // Specifies that you don't want to also generate a universal APK that includes all ABIs. isUniversalApk = false } } }
जिन एबीआई के साथ काम करता है उनकी सूची देखने के लिए, काम करने वाले एबीआई पर जाएं.
ऐसे प्रोजेक्ट जिनमें नेटिव/C++ कोड नहीं है
नेटिव/C++ कोड के बिना प्रोजेक्ट के लिए, बिल्ड वैरिएंट पैनल में दो कॉलम होते हैं: मॉड्यूल और ऐक्टिव बिल्ड वैरिएंट. इन्हें पहले फ़िगर में दिखाया गया है.

पहली इमेज. बिल्ड वैरिएंट पैनल में, ऐसे प्रोजेक्ट के लिए दो कॉलम होते हैं जिनमें नेटिव/C++ कोड नहीं होता.
मॉड्यूल के लिए ऐक्टिव बिल्ड वैरिएंट वैल्यू से यह तय होता है कि एडिटर में कौन-सा बिल्ड वैरिएंट डिप्लॉय किया गया है और दिख रहा है. वैरिएंट के बीच स्विच करने के लिए, किसी मॉड्यूल के लिए चालू बिल्ड वैरिएंट सेल पर क्लिक करें और सूची फ़ील्ड से मनचाहा वैरिएंट चुनें.
नेटिव/C++ कोड वाले प्रोजेक्ट
नेटिव/C++ कोड वाले प्रोजेक्ट के लिए, बिल्ड वैरिएंट पैनल में तीन कॉलम होते हैं: मॉड्यूल, चालू बिल्ड वैरिएंट, और चालू ABI. इन्हें इमेज 2 में दिखाया गया है.
दूसरी इमेज. Build Variants पैनल, नेटिव/C++ कोड वाले प्रोजेक्ट के लिए Active ABI कॉलम जोड़ता है.
मॉड्यूल के लिए ऐक्टिव बिल्ड वैरिएंट वैल्यू से यह तय होता है कि कौनसे बिल्ड वैरिएंट को डिप्लॉय किया गया है और वह एडिटर में दिखता है. नेटिव मॉड्यूल के लिए, चालू ABI वैल्यू से यह तय होता है कि एडिटर कौनसे ABI का इस्तेमाल करेगा. हालांकि, इससे यह तय नहीं होता कि कौनसे ABI को डिप्लॉय किया जाएगा.
बिल्ड टाइप या ABI बदलने के लिए:
- चालू बिल्ड वैरिएंट या चालू ABI कॉलम की सेल पर क्लिक करें.
- सूची फ़ील्ड से, अपनी पसंद का वैरिएंट या ABI चुनें. नया सिंक अपने-आप शुरू हो जाता है.
किसी ऐप्लिकेशन या लाइब्रेरी मॉड्यूल के लिए, किसी भी कॉलम में बदलाव करने पर, यह बदलाव उससे जुड़ी सभी लाइनों पर लागू होता है.
वर्शनिंग की सुविधा कॉन्फ़िगर करना
डिफ़ॉल्ट रूप से, जब Gradle एक से ज़्यादा APK जनरेट करता है, तो हर APK में वर्शन की एक जैसी जानकारी होती है. यह जानकारी, मॉड्यूल-लेवल की build.gradle या build.gradle.kts फ़ाइल में दी गई होती है. Google Play Store, एक ही ऐप्लिकेशन के लिए कई APK की अनुमति नहीं देता है. इन सभी APK के वर्शन की जानकारी एक जैसी होती है. इसलिए, आपको यह पक्का करना होगा कि Play Store पर अपलोड करने से पहले, हर APK में यूनीक
versionCode हो.
मॉड्यूल-लेवल की build.gradle फ़ाइल को कॉन्फ़िगर करके, हर APK के लिए versionCode को बदला जा सकता है. मैपिंग बनाकर, कॉन्फ़िगर किए गए हर एबीआई के लिए एक यूनीक संख्या वाली वैल्यू असाइन की जा सकती है. इससे एक से ज़्यादा APK के लिए, आउटपुट वर्शन कोड को ऐसी वैल्यू से बदला जा सकता है जो defaultConfig या productFlavors ब्लॉक में तय किए गए वर्शन कोड को एबीआई को असाइन की गई संख्या वाली वैल्यू के साथ जोड़ती है.
यहां दिए गए उदाहरण में, x86 ABI के लिए एपीके को 2004 का versionCode मिलता है. वहीं, x86_64 ABI के लिए एपीके को 3004 का versionCode मिलता है.
वर्शन कोड को ज़्यादा अंतर से असाइन करने पर, जैसे कि 1000, आपको बाद में अपने ऐप्लिकेशन को अपडेट करने की ज़रूरत पड़ने पर यूनीक वर्शन कोड असाइन करने की अनुमति मिलती है. उदाहरण के लिए, अगर बाद के अपडेट में defaultConfig.versionCode को 5 पर दोहराया जाता है, तो Gradle, x86 APK को 2005 और x86_64 APK को 3005 का versionCode असाइन करता है.
अहम जानकारी: अगर आपकी बिल्ड में यूनिवर्सल APK शामिल है, तो उसे versionCode असाइन करें. यह versionCode, आपके अन्य APK के versionCode से कम होना चाहिए.
Google Play Store, आपके ऐप्लिकेशन का वह वर्शन इंस्टॉल करता है जो टारगेट डिवाइस के साथ काम करता हो और जिसमें सबसे ज़्यादा versionCode हो. इसलिए, यूनिवर्सल APK को कम versionCode असाइन करने से यह पक्का होता है कि Google Play Store, यूनिवर्सल APK पर वापस जाने से पहले आपके किसी एक APK को इंस्टॉल करने की कोशिश करे. नीचे दिए गए सैंपल कोड में, इस समस्या को हल करने के लिए यूनिवर्सल APK के डिफ़ॉल्ट versionCode को नहीं बदला गया है.
Groovy
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // Map for the version code that gives each ABI a value. ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3] import com.android.build.OutputFile // For each APK output variant, override versionCode with a combination of // ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. android.applicationVariants.all { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.each { output -> // Stores the value of ext.abiCodes that is associated with the ABI for this variant. def baseAbiVersionCode = // Determines the ABI for this variant and returns the mapped value. project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiVersionCode != null) { // Assigns the new version code to versionCodeOverride, which changes the // version code for only the output APK, not for the variant itself. Skipping // this step causes Gradle to use the value of variant.versionCode for the APK. output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode } } }
Kotlin
android { ... defaultConfig { ... versionCode = 4 } splits { ... } } // Map for the version code that gives each ABI a value. val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3) import com.android.build.api.variant.FilterConfiguration.FilterType.* // For each APK output variant, override versionCode with a combination of // abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. androidComponents { onVariants { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == ABI }?.identifier // Stores the value of abiCodes that is associated with the ABI for this variant. val baseAbiCode = abiCodes[name] // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiCode != null) { // Assigns the new version code to output.versionCode, which changes the version code // for only the output APK, not for the variant itself. output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0)) } } } }
वैकल्पिक वर्शन कोड स्कीम के ज़्यादा उदाहरणों के लिए, वर्शन कोड असाइन करना लेख पढ़ें.
कई APK बनाना
एक से ज़्यादा APK बनाने के लिए, मॉड्यूल-लेवल की build.gradle या build.gradle.kts फ़ाइल को कॉन्फ़िगर करने के बाद, प्रोजेक्ट पैन में फ़िलहाल चुने गए मॉड्यूल के लिए सभी APK बनाने के लिए, बनाएं > APK बनाएं पर क्लिक करें. Gradle, प्रोजेक्ट की build/outputs/apk/ डायरेक्ट्री में मौजूद हर ABI के लिए APK बनाता है.
Gradle, हर उस ABI के लिए एक APK बनाता है जिसके लिए आपने एक से ज़्यादा APK कॉन्फ़िगर किए हैं.
उदाहरण के लिए, यहां दिया गया build.gradle स्निपेट, x86 और x86_64 एबीआइ के लिए एक से ज़्यादा APK बनाने की सुविधा देता है:
Groovy
... splits { abi { enable true reset() include "x86", "x86_64" } }
Kotlin
... splits { abi { isEnable = true reset() include("x86", "x86_64") } }
उदाहरण के तौर पर दिए गए कॉन्फ़िगरेशन के आउटपुट में, ये चार APK शामिल हैं:
app-X86-release.apk: इसमेंx86एबीआई के लिए कोड और संसाधन शामिल होते हैं.app-X86_64-release.apk: इसमेंx86_64एबीआई के लिए कोड और संसाधन शामिल होते हैं.
एबीआई के आधार पर एक से ज़्यादा APK बनाते समय, Gradle सिर्फ़ ऐसा APK जनरेट करता है जिसमें सभी एबीआई के लिए कोड और संसाधन शामिल होते हैं. ऐसा तब होता है, जब आपने अपनी build.gradle फ़ाइल (Groovy के लिए) में splits.abi ब्लॉक में universalApk true या अपनी build.gradle.kts फ़ाइल (Kotlin स्क्रिप्ट के लिए) में splits.abi ब्लॉक में isUniversalApk = true तय किया हो.
APK फ़ाइल के नाम का फ़ॉर्मैट
एक से ज़्यादा APK बनाने के दौरान, Gradle इन स्कीम का इस्तेमाल करके APK के फ़ाइल नाम जनरेट करता है:
modulename-ABI-buildvariant.apk
स्कीम के कॉम्पोनेंट ये हैं:
-
modulename - इससे बनाए जा रहे मॉड्यूल का नाम पता चलता है.
-
ABI -
अगर ABI के लिए एक से ज़्यादा APK चालू किए गए हैं, तो APK के लिए ABI तय करता है. जैसे,
x86. -
buildvariant -
इससे पता चलता है कि कौनसे बिल्ड वैरिएंट को बनाया जा रहा है. जैसे,
debug.