Android ডেভেলপমেন্টে Build Variant হল build type এবং product flavor-এর একটি সংমিশ্রণ যা নির্ধারণ করে কিভাবে APK বা AAB তৈরি হবে: কোন প্যারামিটার, রিসোর্স এবং কোড সহ। প্রতিটি বিল্ড ভেরিয়েন্ট তার নিজস্ব applicationId, সইং কী এবং অন্তর্ভুক্ত নির্ভরতা সহ একটি পৃথক Gradle কনফিগারেশন উপস্থাপন করে। Google Android Developers, 2025 অনুসারে, Build Variants-এর সঠিক কনফিগারেশন প্রতিটি ভেরিয়েন্টের জন্য অপ্রয়োজনীয় রিসোর্স বাদ দিয়ে বিল্ড সময় 40% পর্যন্ত কমিয়ে দেয়। বিল্ড ভেরিয়েন্ট সিস্টেম আধুনিক Android প্রকল্পে কনফিগারেশন ব্যবস্থাপনার ভিত্তি।
মূল পয়েন্ট
Build Variant হল একটি Build Type এবং একটি Product Flavor-এর সংমিশ্রণের ফলাফল। যদি প্রকল্পে কোনো Product Flavors সংজ্ঞায়িত না থাকে, তাহলে Build Variant Build Type-এর সাথে মিলে যায়। Gradle স্বয়ংক্রিয়ভাবে সমস্ত FlavorDimensions, Product Flavors এবং Build Types-এর কার্টেজিয়ান গুণফল হিসাবে ভেরিয়েন্টের সম্পূর্ণ সেট তৈরি করে। উদাহরণস্বরূপ, free/paid flavors এবং debug/release types-এর জন্য ৪টি ভেরিয়েন্ট তৈরি হবে: freeDebug, freeRelease, paidDebug, paidRelease।
প্রতিটি Build Variant <Flavor><Type> ফরম্যাটে তার নিজস্ব নাম পায় যেখানে flavor বড় হাতের অক্ষরে লেখা হয়। Gradle এই ভেরিয়েন্টের জন্য পৃথক টাস্ক তৈরি করে: assembleFreeDebug, installFreeDebug, bundleFreeRelease। Android Studio-তে, Build Variants প্যানেল (View → Tool Windows → Build Variants)-এর মাধ্যমে ভেরিয়েন্টের মধ্যে সুইচ করা যায়। একটি ভেরিয়েন্ট নির্বাচন করলে প্রভাবিত হয় কোন কোড কম্পাইল হবে, কোন রিসোর্স অন্তর্ভুক্ত হবে এবং কোন APK/AAB তৈরি হবে।
Build Variants সিস্টেম তিনটি মূল কাজ সমাধান করে: বিভিন্ন পরিবেশের (dev/staging/production) জন্য কনফিগারেশন আলাদা করা, একটি অ্যাপের একাধিক সংস্করণ (free/paid) তৈরি করা এবং বিল্ডের A/B পরীক্ষা করা। Build Variants ছাড়া, ডেভেলপারদের ম্যানুয়ালি ফ্ল্যাগ এবং কনফিগারেশন পরিবর্তন করতে হবে, যা মানবিক ত্রুটির দিকে নিয়ে যায়। Gradle Inc., 2024-এর একটি গবেষণা অনুসারে, Build Variants বাস্তবায়ন করলে তিন বা ততোধিক স্থাপন পরিবেশ বিশিষ্ট প্রকল্পে বিল্ড ত্রুটি 60% কমে যায়।
AGP (Android Gradle Plugin) কনফিগারেশন পর্যায়ে সমস্ত সংমিশ্রণ গণনা করে। যদি একটি প্রকল্পে যথাক্রমে দুটি এবং তিনটি flavor সহ দুটি মাত্রা থাকে, তাহলে Gradle 2 × 2 × 3 = 12 সংমিশ্রণ তৈরি করবে, যা Build Types-এর সংখ্যা (সাধারণত 2) দ্বারা গুণিত হয়। প্রতিটি সংমিশ্রণ একটি অনন্য নাম এবং টাস্কের সেট পায়। AGP স্বয়ংক্রিয়ভাবে প্রতিটি ভেরিয়েন্টের জন্য একটি source set যোগ করে: src/freeDebug/, src/paidRelease/, সেইসাথে সাধারণ src/free/ এবং src/debug/। রিসোর্স পড়ার অগ্রাধিকার: variant → flavor → type → main।
// উদাহরণ: 4টি Build Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// মোট: 2 × 2 × 2 = 8টি ভেরিয়েন্ট
android {
flavorDimensions "version", "server"
productFlavors {
demo { dimension "version" }
prod { dimension "version" }
mock { dimension "server" }
live { dimension "server" }
}
}
Build Type নির্ধারণ করে কিভাবে অ্যাপ্লিকেশন তৈরি করতে হবে — ডিবাগ তথ্য সহ বা ছাড়া, অপ্টিমাইজেশন সহ বা ছাড়া, কোন সইং সহ। Product Flavor নির্ধারণ করে কী তৈরি করতে হবে — পণ্যের কোন সংস্করণ। Build Type হল একটি বিল্ড মেকানিজম (debug, release, staging)। Product Flavor হল একটি পণ্য ভেরিয়েন্ট (free, paid, enterprise, demo)। উভয় ধারণাই অর্থোগোনাল: যেকোনো Build Type যেকোনো Product Flavor-এ প্রয়োগ করা যেতে পারে।
ডিফল্ট Build Types-এর মধ্যে debug (debuggable=true, minification=false, signing=debug.keystore) এবং release (debuggable=false, minification=true, signing=production.keystore) অন্তর্ভুক্ত। ডিফল্ট Product Flavor একটিমাত্র, নামহীন (কার্যকরভাবে main source set)। ডেভেলপাররা তাদের নিজস্ব Build Types (যেমন, “staging” যেখানে debuggable=true এবং minification=true) এবং যেকোনো সংখ্যক Product Flavors যোগ করতে পারেন। আরেকটি পার্থক্য হল যে Build Types-কে মাত্রায় গ্রুপ করা যায় না, কিন্তু Product Flavors-কে যায়।
মূল ব্যবহারিক পার্থক্য: defaultConfig build.gradle-এ সমস্ত Variants-এ প্রযোজ্য কিন্তু productFlavors এবং buildTypes-এ ওভাররাইড করা যেতে পারে। buildType-এ যোগ করা BuildConfigField সেই ধরণের সমস্ত flavors-এ দৃশ্যমান, যেখানে productFlavor-এ যোগ করা সেই flavor-এর সমস্ত ধরণে দৃশ্যমান। যদি একটি ফিল্ড উভয়েই সংজ্ঞায়িত হয়, তবে buildType অগ্রাধিকার পায় (এটি শৃঙ্খলে শেষ প্রয়োগ করা হয়)।
| বৈশিষ্ট্য | Build Type | Product Flavor |
|---|---|---|
| উদ্দেশ্য | কিভাবে তৈরি করতে হবে | কী তৈরি করতে হবে |
| উদাহরণ | debug, release, staging | free, paid, demo, enterprise |
| ডিফল্ট | debug + release | একটি (main) |
| Source Set | src/debug/, src/release/ | src/free/, src/paid/ |
| মাত্রা | না | flavorDimensions |
| প্রয়োগের ক্রম | flavor-এর পরে, ওভাররাইড করে | defaultConfig-এর পরে |
| BuildConfigField | flavor ওভাররাইড করে | defaultConfig ওভাররাইড করে |
Build Variants কনফিগারেশন মডিউল-স্তরের build.gradle ফাইলের android ব্লকে করা হয়। প্রথমে buildTypes তাদের প্যারামিটার সহ ঘোষণা করা হয়, তারপর flavorDimensions এবং productFlavors। Gradle এই ঘোষণার ভিত্তিতে স্বয়ংক্রিয়ভাবে ভেরিয়েন্ট তৈরি করে। প্রতিটি ভেরিয়েন্ট মডিউলের defaultConfig উত্তরাধিকার সূত্রে পায়, নির্দিষ্ট ফিল্ড ওভাররাইড করে। ঘোষণার ক্রম অগ্রাধিকারকে প্রভাবিত করে: buildTypes productFlavors-এর পরে প্রয়োগ হয়।
Gradle স্ক্রিপ্টে একটি নির্দিষ্ট Build Variant অ্যাক্সেস করতে, android.applicationVariants (app মডিউলের জন্য) বা android.libraryVariants (লাইব্রেরি মডিউলের জন্য) ব্যবহার করুন। এটি একটি সংগ্রহ যা কনফিগারেশন রানটাইমে প্রতিটি ভেরিয়েন্টের কনফিগারেশন পরিবর্তন করতে পুনরাবৃত্তি করা যেতে পারে। উদাহরণস্বরূপ, আপনি “demo” শব্দ ধারণকারী সমস্ত ভেরিয়েন্টের জন্য প্রোগ্রামেটিকভাবে buildConfigField যোগ করতে পারেন।
Android Gradle Plugin 8.x onVariants-এর জন্য সমর্থন যুক্ত করেছে — lambdas-এর মাধ্যমে ভেরিয়েন্ট কনফিগার করার জন্য একটি পরিষ্কার API। পুরানো API (variantOutput, variantFilter) অবচিত হিসাবে চিহ্নিত করা হয়েছে। লাইব্রেরি মডিউলের জন্য onEach-এর সাথে onVariants ব্যবহার করার পরামর্শ দেওয়া হয়। variantOutput থেকে onVariants-এ মাইগ্রেট করা AGP 7.x থেকে 8.x-এ আপগ্রেড করার সময় একটি প্রস্তাবিত পদক্ষেপ।
android {
buildTypes {
debug {
debuggable true
minification false
signingConfig signingConfigs.debug
}
release {
debuggable false
minification true
proguardFiles "proguard-rules.pro"
signingConfig signingConfigs.release
}
staging {
debuggable true
minification true
versionNameSuffix "-staging"
}
}
flavorDimensions "tier", "region"
productFlavors {
free { dimension "tier" }
paid { dimension "tier" }
us { dimension "region" }
eu { dimension "region" }
}
}
android.onVariants { variant ->
if (variant.name.contains("Demo")) {
variant.setEnabled(false)
}
}
প্রতিটি Build Variant source sets-এর নিজস্ব শ্রেণিবিন্যাস পায় — সোর্স কোড, রিসোর্স এবং ম্যানিফেস্ট সম্বলিত ডিরেক্টরি। একটি source set src/<variantName>/-এ অবস্থিত (যেমন, src/freeDebug/) এবং java/, res/, AndroidManifest.xml, assets/ ধারণ করতে পারে। যদি একটি ফাইল ভেরিয়েন্টের source set-এ বিদ্যমান থাকে, তবে এটি মূল source set (src/main/) থেকে একই নামের ফাইলটিকে ওভাররাইড করে। রিসোর্সের জন্য, প্রতিস্থাপনের পরিবর্তে মার্জিং ঘটে — সিস্টেম সমস্ত সক্রিয় source sets থেকে রিসোর্স মার্জ করে, ভেরিয়েন্ট-নির্দিষ্টগুলিকে অগ্রাধিকার দেয়।
Build Variant-এর জন্য source sets একটি শৃঙ্খলে তৈরি হয়: src/main/ → src/flavor/ → src/type/ → src/flavorType/। উদাহরণস্বরূপ, paidRelease-এর জন্য, প্রথমে main প্রয়োগ হয়, তারপর paid, তারপর release, তারপর paidRelease। প্রতিটি পরবর্তী source set আগেরটিকে ওভাররাইড করে। এর মানে হল src/release/res/values/strings.xml src/paid/-এর একই স্ট্রিংগুলিকে ওভাররাইড করবে, কিন্তু src/paidRelease/res/-এর আরও বেশি অগ্রাধিকার রয়েছে।
ভেরিয়েন্টের জন্য source sets ব্যবহার করা রিসোর্স কাস্টমাইজ করার প্রস্তাবিত উপায়। কোডে BuildConfig.FLAVOR চেক করে এবং লজিক শাখাবদ্ধ করার পরিবর্তে, আপনি কেবল ভিন্ন ফাইল ভিন্ন source sets-এ রাখতে পারেন। উদাহরণস্বরূপ, free এবং paid সংস্করণের আইকন যথাক্রমে src/free/res/ এবং src/paid/res/-এ যায় এবং ভিন্ন অনুমতি সহ AndroidManifest src/free/AndroidManifest.xml এবং src/paid/AndroidManifest.xml-এ যায়। এটি পরিষ্কার, দ্রুত (রিসোর্স কম্পাইল হয়, রানটাইমে চেক করা হয় না) এবং আরও নিরাপদ (আপনি কোড বাগের কারণে ভুলবশত বিনামূল্যের সংস্করণে অর্থপ্রদানের কার্যকারিতা অন্তর্ভুক্ত করতে পারবেন না)।
মাল্টি-মডিউল প্রকল্পে, প্রতিটি মডিউল (লাইব্রেরি) এর নিজস্ব Build Variants থাকতে পারে। AGP স্বয়ংক্রিয়ভাবে ভেরিয়েন্ট সিঙ্ক্রোনাইজ করে: যদি app মডিউল paidRelease তৈরি করে, তবে সমস্ত নির্ভরশীল লাইব্রেরিও paidRelease-এর সাথে সম্পর্কিত তাদের ভেরিয়েন্টে তৈরি হয়। সমস্যা দেখা দেয় যখন একটি লাইব্রেরিতে product flavors নেই কিন্তু app মডিউলে আছে — তখন লাইব্রেরিটি একবার তৈরি হয় (প্রকারের উপর নির্ভর করে release বা debug)।
লাইব্রেরি মডিউলের জন্য, Build Variant ডিফল্টরূপে app মডিউলের Build Type-এর সাথে মেলে, কারণ লাইব্রেরিতে product flavors থাকে না। যদি একটি লাইব্রেরিকে app মডিউলের flavor-এর সাথে খাপ খাইয়ে নিতে হয়, তবে লাইব্রেরিতে একই flavorDimensions এবং productFlavors ঘোষণা করতে হবে। AGP নামের সঠিক মিলের মাধ্যমে flavors মেলে। Gradle রুট প্রকল্পে subprojects বা Convention Plugins ব্যবহার করে বিল্ড কনফিগারেশনের মাধ্যমে flavors সিঙ্ক্রোনাইজ করার পরামর্শ দেয়।
AGP 8.1 থেকে শুরু করে, লাইব্রেরিগুলি multiple variants প্রকাশ করতে পারে — একসাথে maven রিপোজিটরিতে সমস্ত লাইব্রেরি ভেরিয়েন্ট প্রকাশ করা। এটি সেই সমস্যার সমাধান করে যখন app মডিউল একটি অর্থপ্রদানের flavor ব্যবহার করে কিন্তু লাইব্রেরিটি শুধুমাত্র বিনামূল্যের জন্য প্রকাশিত হয়। Multiple variants publishing (MVP) নির্ভরশীল প্রকল্পকে স্বয়ংক্রিয়ভাবে প্রয়োজনীয় ভেরিয়েন্ট নির্বাচন করতে দেয়। MVP সক্ষম করতে, লাইব্রেরির build.gradle-এ publishing { multipleVariants { ... } } যোগ করুন।
কখনও কখনও কিছু Build Variants নিষ্ক্রিয় করা প্রয়োজন — উদাহরণস্বরূপ, যদি mockRelease সংমিশ্রণটি অর্থহীন হয় (মক সার্ভার প্রোডাকশনে যাওয়া উচিত নয়)। Gradle variantFilter প্রদান করে — একটি DSL ব্লক যেখানে আপনি প্রতিটি ভেরিয়েন্টের বৈশিষ্ট্য পরীক্ষা করতে পারেন এবং setIgnore(true)-এর মাধ্যমে এটি নিষ্ক্রিয় করতে পারেন। VariantFilter টাস্ক তৈরির আগে, কনফিগারেশন পর্যায়ে প্রয়োগ করা হয়, তাই একটি নিষ্ক্রিয় ভেরিয়েন্ট assemble এবং install টাস্ক তৈরি করে না।
বিল্ড দ্রুত করার জন্যও ফিল্টারিং উপযোগী। যদি একটি প্রকল্পে 8টি ভেরিয়েন্ট থাকে কিন্তু একজন ডেভেলপার শুধুমাত্র একটিতে কাজ করে, বাকি 7টি ভেরিয়েন্ট এখনও কনফিগারেশনের মধ্য দিয়ে যায়। variantFilter ব্যবহার করার সময়, নিষ্ক্রিয় ভেরিয়েন্ট টাস্ক তৈরি করে না, যা 6+ flavor মাত্রা বিশিষ্ট প্রকল্পের জন্য কনফিগারেশন সময় 30-50% কমিয়ে দেয়। CI/CD-তে, আপনি কমান্ড লাইন প্যারামিটার -PbuildOnly=paidRelease-এর মাধ্যমে ডায়নামিকভাবে ভেরিয়েন্ট ফিল্টার করতে পারেন।
android {
variantFilter { variant ->
// release এবং production-এর জন্য demo নিষ্ক্রিয় করতে mock বন্ধ করুন
def names = variant.flavors*.name
def isMock = names.contains("mock")
def isDemo = names.contains("demo")
def isRelease = variant.buildType.name == "release"
if ((isMock && isRelease) || (isDemo && !isMock)) {
variant.setIgnore(true)
}
}
}
// প্যারামিটারের মাধ্যমে ডায়নামিক ফিল্টারিং
if (project.hasProperty("buildOnly")) {
def target = project.property("buildOnly")
android.variantFilter { variant ->
variant.setIgnore(variant.name != target)
}
}
প্রায়শই জিজ্ঞাসিত প্রশ্ন
কোনো সীমা নেই, কিন্তু Gradle সমস্ত flavors এবং প্রকারের কার্টেজিয়ান গুণফল তৈরি করে। আপনার যদি 3টি মাত্রা থাকে যার প্রতিটিতে 3টি flavor এবং 3টি build type থাকে, তাহলে আপনি 27টি ভেরিয়েন্ট পাবেন। অত্যধিক ভেরিয়েন্ট কনফিগারেশন ধীর করে দেয়। একটি মডিউলে 10-12টির বেশি ভেরিয়েন্ট না রাখার পরামর্শ দেওয়া হয়।
flavorDimensions Product Flavors-কে স্বাধীন অক্ষে গ্রুপ করে। উদাহরণস্বরূপ, “tier” মাত্রা (free, paid) এবং “region” মাত্রা (us, eu)। মাত্রা ছাড়া, সমস্ত flavors একটি অক্ষের অন্তর্গত, এবং Gradle সবগুলি থেকে শুধুমাত্র একটি flavor নির্বাচন করবে (আপনি free+us এবং paid+eu আলাদা ভেরিয়েন্ট হিসাবে রাখতে পারবেন না)।
productFlavor বা buildType ব্লকে, applicationId নির্দিষ্ট করুন। উদাহরণস্বরূপ, বিনামূল্যের সংস্করণের জন্য: free { applicationId “com.example.app.free” }। ম্যানিফেস্টে, ${applicationId} ব্যবহার করুন — Gradle স্বয়ংক্রিয়ভাবে মান প্রতিস্থাপন করবে। এটি একটি ডিভাইসে উভয় ভেরিয়েন্ট ইনস্টল করার অনুমতি দেয়।
iOS-এ, Build Variants-এর সমতুল্য হল Scheme + Configuration-এর সংমিশ্রণ। Xcode Schemes বিভিন্ন প্যারামিটার সহ Debug/Release কনফিগারেশনের মাধ্যমে কনফিগার করা হয়। একাধিক সংস্করণের (free/paid) জন্য, Build Configurations এবং Preprocessor Macros ব্যবহার করা হয়। Android-এ, ধারণাটি আরও আনুষ্ঠানিক এবং Gradle-এ অন্তর্নির্মিত।
হ্যাঁ, প্রতিটি ভেরিয়েন্টের APK আকার আলাদা হতে পারে। Debug বিল্ডে ডিবাগ তথ্য, SDK এবং অসমর্থিত রিসোর্স অন্তর্ভুক্ত থাকে। minification এবং resource shrinking সহ Release বিল্ড ন্যূনতম আকার তৈরি করে। Product Flavor আকারকেও প্রভাবিত করে: অর্থপ্রদানের লাইব্রেরি ছাড়া বিনামূল্যের সংস্করণ সেই লাইব্রেরির আকারের কারণে অর্থপ্রদানের সংস্করণের চেয়ে ছোট হবে।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন