একাধিক APK তৈরি করুন

সতর্কতা: আগস্ট ২০২১ সাল থেকে, সমস্ত নতুন অ্যাপ অ্যাপ বান্ডেল হিসেবে প্রকাশ করতে হবে। আপনি যদি আপনার অ্যাপটি Google Play তে প্রকাশ করেন, তাহলে একটি Android অ্যাপ বান্ডেল তৈরি করুন এবং আপলোড করুন। যখন আপনি এটি করেন, তখন Google Play স্বয়ংক্রিয়ভাবে প্রতিটি ব্যবহারকারীর ডিভাইস কনফিগারেশনের জন্য অপ্টিমাইজ করা APK তৈরি করে এবং পরিবেশন করে, তাই তারা কেবল আপনার অ্যাপ চালানোর জন্য প্রয়োজনীয় কোড এবং সংস্থানগুলি ডাউনলোড করে। আপনি যদি এমন কোনও দোকানে প্রকাশ করেন যা AAB ফর্ম্যাট সমর্থন করে না, তাহলে একাধিক APK প্রকাশ করা কার্যকর। সেক্ষেত্রে, আপনাকে প্রতিটি APK নিজেই তৈরি, স্বাক্ষর এবং পরিচালনা করতে হবে।

যদিও সম্ভব হলে আপনার সমস্ত টার্গেট ডিভাইসগুলিকে সমর্থন করার জন্য একটি একক APK তৈরি করা ভাল, তবে একাধিক অ্যাপ্লিকেশন বাইনারি ইন্টারফেস (ABI) সমর্থনকারী ফাইলগুলির কারণে এটি একটি খুব বড় APK তৈরি করতে পারে। আপনার APK এর আকার কমানোর একটি উপায় হল একাধিক APK তৈরি করা যাতে নির্দিষ্ট ABI-এর জন্য ফাইল থাকে।

Gradle পৃথক APK তৈরি করতে পারে যাতে প্রতিটি ABI-এর জন্য নির্দিষ্ট কোড এবং রিসোর্স থাকে। এই পৃষ্ঠায় বর্ণনা করা হয়েছে যে কীভাবে আপনার বিল্ডকে একাধিক APK তৈরি করার জন্য কনফিগার করবেন। যদি আপনার অ্যাপের বিভিন্ন সংস্করণ তৈরি করতে হয় যা ABI-এর উপর ভিত্তি করে নয়, তাহলে বিল্ড ভেরিয়েন্ট ব্যবহার করুন।

একাধিক APK-এর জন্য আপনার বিল্ড কনফিগার করুন

একাধিক APK-এর জন্য আপনার বিল্ড কনফিগার করতে, আপনার মডিউল-লেভেল build.gradle ফাইলে একটি splits ব্লক যোগ করুন। splits ব্লকের মধ্যে, একটি abi ব্লক প্রদান করুন যা নির্দিষ্ট করে যে আপনি Gradle-কে প্রতি-ABI APK কীভাবে তৈরি করতে চান।

ABI-এর জন্য একাধিক APK কনফিগার করুন

বিভিন্ন ABI-এর জন্য আলাদা APK তৈরি করতে, আপনার splits ব্লকের ভিতরে একটি abi ব্লক যোগ করুন। আপনার abi ব্লকে, পছন্দসই ABI-এর একটি তালিকা প্রদান করুন।

নিম্নলিখিত গ্রেডল ডিএসএল বিকল্পগুলি প্রতি এবিআই-তে একাধিক APK কনফিগার করতে ব্যবহৃত হয়:

গ্রুভির জন্য enable , অথবা কোটলিন স্ক্রিপ্টের জন্য isEnable
যদি আপনি এই উপাদানটিকে true তে সেট করেন, তাহলে Gradle আপনার সংজ্ঞায়িত ABI গুলির উপর ভিত্তি করে একাধিক APK তৈরি করে। ডিফল্ট মান হল false
exclude
কমা দ্বারা পৃথক করা ABI গুলির একটি তালিকা নির্দিষ্ট করে যার জন্য আপনি Gradle কে আলাদা APK তৈরি করতে দিতে চান না। যদি আপনি বেশিরভাগ ABI গুলির জন্য APK তৈরি করতে চান কিন্তু আপনার অ্যাপ সমর্থন করে না এমন কয়েকটি ABI বাদ দিতে চান তবে exclude ব্যবহার করুন।
reset()

ABI-এর ডিফল্ট তালিকা সাফ করে। আপনি যে ABI গুলি যোগ করতে চান তা নির্দিষ্ট করতে শুধুমাত্র include উপাদানের সাথে মিলিত হলেই ব্যবহার করুন।

নিচের স্নিপেটটি ABI-এর তালিকাকে 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
কমা দ্বারা পৃথক করা ABI গুলির একটি তালিকা নির্দিষ্ট করে যার জন্য আপনি Gradle কে APK তৈরি করতে চান। ABI গুলির একটি সঠিক তালিকা নির্দিষ্ট করতে শুধুমাত্র reset() এর সাথে একত্রে ব্যবহার করুন।
গ্রুভির জন্য universalApk , অথবা কোটলিন স্ক্রিপ্টের জন্য isUniversalApk

যদি true , তাহলে Gradle প্রতি-ABI APK ছাড়াও একটি সর্বজনীন APK তৈরি করে। একটি সর্বজনীন APK-তে একটি একক APK-তে সমস্ত ABI-এর জন্য কোড এবং সংস্থান থাকে। ডিফল্ট মান হল false

নিম্নলিখিত উদাহরণটি প্রতিটি ABI-এর জন্য একটি পৃথক APK তৈরি করে: x86 এবং x86_64 । এটি reset() ব্যবহার করে শুরুতে ABI-এর একটি খালি তালিকা দিয়ে করা হয়, তারপরে include এর মাধ্যমে ABI-এর একটি তালিকা তৈরি করা হয় যেখানে প্রতিটি APK পায়।

খাঁজকাটা

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
    }
  }
}

কোটলিন

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
    }
  }
}

সমর্থিত ABI-এর তালিকার জন্য, সমর্থিত ABI-গুলি দেখুন।

নেটিভ/সি++ কোড ছাড়া প্রকল্প

নেটিভ/C++ কোড ছাড়া প্রকল্পগুলির জন্য, বিল্ড ভ্যারিয়েন্ট প্যানেলে দুটি কলাম রয়েছে: মডিউল এবং অ্যাক্টিভ বিল্ড ভ্যারিয়েন্ট , যেমনটি চিত্র 1-এ দেখানো হয়েছে।

বিল্ড ভেরিয়েন্ট প্যানেল
চিত্র ১. বিল্ড ভ্যারিয়েন্ট প্যানেলে নেটিভ/সি++ কোড ছাড়া প্রকল্পগুলির জন্য দুটি কলাম রয়েছে।

মডিউলের জন্য অ্যাক্টিভ বিল্ড ভ্যারিয়েন্ট মান নির্ধারণ করে যে বিল্ড ভ্যারিয়েন্টটি এডিটরে স্থাপন করা হয়েছে এবং দৃশ্যমান। ভ্যারিয়েন্টগুলির মধ্যে স্যুইচ করতে, একটি মডিউলের জন্য অ্যাক্টিভ বিল্ড ভ্যারিয়েন্ট সেলটিতে ক্লিক করুন এবং তালিকা ক্ষেত্র থেকে পছন্দসই ভ্যারিয়েন্টটি নির্বাচন করুন।

নেটিভ/সি++ কোড সহ প্রকল্পগুলি

নেটিভ/C++ কোড সহ প্রকল্পগুলির জন্য, বিল্ড ভ্যারিয়েন্ট প্যানেলে তিনটি কলাম রয়েছে: মডিউল , অ্যাক্টিভ বিল্ড ভ্যারিয়েন্ট এবং অ্যাক্টিভ ABI , যেমনটি চিত্র 2-এ দেখানো হয়েছে।

চিত্র ২. বিল্ড ভেরিয়েন্ট প্যানেলটি নেটিভ/C++ কোড সহ প্রকল্পগুলির জন্য সক্রিয় ABI কলাম যোগ করে।

মডিউলের জন্য অ্যাক্টিভ বিল্ড ভ্যারিয়েন্ট মান নির্ধারণ করে যে বিল্ড ভ্যারিয়েন্টটি স্থাপন করা হয়েছে এবং এডিটরে দৃশ্যমান। নেটিভ মডিউলের জন্য, অ্যাক্টিভ ABI মান নির্ধারণ করে যে এডিটরটি কোন ABI ব্যবহার করে, কিন্তু কী স্থাপন করা হয়েছে তার উপর কোন প্রভাব ফেলে না।

বিল্ড টাইপ বা ABI পরিবর্তন করতে:

  1. অ্যাক্টিভ বিল্ড ভেরিয়েন্ট অথবা অ্যাক্টিভ ABI কলামের জন্য ঘরে ক্লিক করুন।
  2. তালিকা ক্ষেত্র থেকে পছন্দসই রূপ অথবা ABI নির্বাচন করুন। একটি নতুন সিঙ্ক স্বয়ংক্রিয়ভাবে চলে।

একটি অ্যাপ বা লাইব্রেরি মডিউলের জন্য যেকোনো একটি কলাম পরিবর্তন করলে তা সমস্ত নির্ভরশীল সারিতে প্রযোজ্য হবে।

সংস্করণ কনফিগার করুন

ডিফল্টরূপে, যখন Gradle একাধিক APK তৈরি করে, তখন প্রতিটি APK-তে একই সংস্করণের তথ্য থাকে, যেমনটি মডিউল-স্তরের build.gradle বা build.gradle.kts ফাইলে উল্লেখ করা হয়েছে। যেহেতু Google Play Store একই অ্যাপের জন্য একাধিক APK অনুমোদন করে না, কারণ সকলের একই সংস্করণের তথ্য থাকে, তাই Play Store-এ আপলোড করার আগে আপনাকে নিশ্চিত করতে হবে যে প্রতিটি APK-তে একটি অনন্য versionCode আছে।

আপনি আপনার মডিউল-স্তরের build.gradle ফাইলটি প্রতিটি APK এর জন্য versionCode ওভাররাইড করার জন্য কনফিগার করতে পারেন। এমন একটি ম্যাপিং তৈরি করে যা প্রতিটি ABI এর জন্য একটি অনন্য সংখ্যাসূচক মান নির্ধারণ করে যার জন্য আপনি একাধিক APK কনফিগার করেন, আপনি আউটপুট সংস্করণ কোডটিকে এমন একটি মান দিয়ে ওভাররাইড করতে পারেন যা defaultConfig বা productFlavors ব্লকের মধ্যে সংজ্ঞায়িত সংস্করণ কোডকে ABI এর জন্য নির্ধারিত সংখ্যাসূচক মানের সাথে একত্রিত করে।

নিম্নলিখিত উদাহরণে, x86 ABI-এর APK 2004 versionCode পেয়েছে এবং x86_64 ABI 3004 versionCode পেয়েছে।

১০০০ এর মতো বড় বর্ধিতাংশে ভার্সন কোড বরাদ্দ করলে, পরবর্তীতে আপনার অ্যাপ আপডেট করার প্রয়োজন হলে আপনাকে অনন্য ভার্সন কোড বরাদ্দ করতে সাহায্য করবে। উদাহরণস্বরূপ, যদি পরবর্তী আপডেটে defaultConfig.versionCode ৫-এ পুনরাবৃত্তি হয়, তাহলে Gradle x86 APK-তে ২০০৫ এবং x86_64 APK-তে ৩০০৫-এর একটি versionCode বরাদ্দ করে।

টিপস: যদি আপনার বিল্ডে একটি সার্বজনীন APK থাকে, তাহলে এটিকে এমন একটি versionCode বরাদ্দ করুন যা আপনার অন্যান্য APK-এর চেয়ে কম। যেহেতু Google Play Store আপনার অ্যাপের এমন একটি সংস্করণ ইনস্টল করে যা লক্ষ্য ডিভাইসের সাথে সামঞ্জস্যপূর্ণ এবং সর্বোচ্চ versionCode আছে, তাই সার্বজনীন APK-তে একটি নিম্ন versionCode বরাদ্দ করলে নিশ্চিত হয় যে Google Play Store সার্বজনীন APK-তে ফিরে যাওয়ার আগে আপনার APKগুলির একটি ইনস্টল করার চেষ্টা করে। নিম্নলিখিত নমুনা কোডটি একটি সার্বজনীন APK-এর ডিফল্ট versionCode ওভাররাইড না করে এটি পরিচালনা করে।

খাঁজকাটা

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
    }
  }
}

কোটলিন

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 ফাইলটি কনফিগার করার পর, Project প্যানে বর্তমানে নির্বাচিত মডিউলের জন্য সমস্ত APK তৈরি করতে Build > Build APK এ ক্লিক করুন। Gradle Project এর build/outputs/apk/ ডিরেক্টরিতে প্রতিটি ABI এর জন্য APK তৈরি করে।

আপনি একাধিক APK কনফিগার করেন এমন প্রতিটি ABI-এর জন্য Gradle একটি APK তৈরি করে।

উদাহরণস্বরূপ, নিম্নলিখিত build.gradle স্নিপেটটি x86 এবং x86_64 ABI-এর জন্য একাধিক APK তৈরি করতে সক্ষম করে:

খাঁজকাটা

...
  splits {
    abi {
      enable true
      reset()
      include "x86", "x86_64"
    }
  }

কোটলিন

...
  splits {
    abi {
      isEnable = true
      reset()
      include("x86", "x86_64")
    }
  }

উদাহরণ কনফিগারেশনের আউটপুটে নিম্নলিখিত 4টি APK অন্তর্ভুক্ত রয়েছে:

  • app-X86-release.apk : x86 ABI এর কোড এবং রিসোর্স রয়েছে।
  • app-X86_64-release.apk : x86_64 ABI এর কোড এবং রিসোর্স রয়েছে।

ABI-এর উপর ভিত্তি করে একাধিক APK তৈরি করার সময়, Gradle কেবলমাত্র এমন একটি APK তৈরি করে যাতে সমস্ত ABI-এর জন্য কোড এবং রিসোর্স থাকে যদি আপনি আপনার 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