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 کے لیے 4 ویریئنٹس بنائے جائیں گے: 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) کنفیگریشن مرحلے میں تمام امتزاجات کا حساب لگاتا ہے۔ اگر کسی پروجیکٹ میں بالترتیب دو اور تین flavors کے ساتھ دو جہتیں ہیں، تو 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 کو کیا جا سکتا ہے۔
اہم عملی فرق: build.gradle میں defaultConfig تمام 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 سے شروع کرتے ہوئے، لائبریریاں متعدد ویریئنٹس شائع کر سکتی ہیں — تمام لائبریری ویریئنٹس کو ایک ساتھ maven ذخیرہ میں شائع کرنا۔ یہ اس مسئلے کو حل کرتا ہے جب app ماڈیول بلا معاوضہ flavor استعمال کرتا ہے لیکن لائبریری صرف مفت کے لیے شائع ہوتی ہے۔ متعدد ویریئنٹس کی اشاعت (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 کے لیے mock اور production کے لیے demo کو غیر فعال کریں
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 flavors اور 3 build types ہیں، تو آپ کو 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں