Build Type — چیست، پیکربندی debug و release در Gradle

نویسنده: IT Sectr منتشر شده: 2026-05-30 زمان مطالعه: 9 دقیقه

Build Type در توسعه Android پیکربندی Gradle است که نحوه ساخت برنامه را تعیین می‌کند: با دیباگ یا بدون آن، با بهینه‌سازی کد یا بدون آن، با چه گواهی امضا. Android Gradle Plugin دو Build Type استاندارد — debug و release ارائه می‌دهد و توسعه‌دهنده می‌تواند انواع سفارشی مانند staging یا benchmark اضافه کند. به گفته Google Android Developers, 2025، پیکربندی صحیح Build Type اندازه APK را تا 60% با استفاده از minification و resource shrinking کاهش می‌دهد. هر Build Type با Product Flavors در Build Variant ترکیب می‌شود.

نکات کلیدی

  • Build Type — پیکربندی ساخت با پارامترهای debuggable، minification، signing.
  • Debug — نسخه دیباگ با debuggable=true، minification=false، debug.keystore.
  • Release — نسخه نهایی با debuggable=false، minification=true، production signing.
  • ProGuard و R8 در نسخه‌های release مبهم‌سازی، بهینه‌سازی و فشرده‌سازی کد را انجام می‌دهند.
  • BuildConfigField امکان تعریف متغیرهای قابل دسترس در کد را به صورت جداگانه برای هر نوع فراهم می‌کند.

Build Type چیست؟

Build Type عنصری از پیکربندی Gradle پروژه Android است که پارامترهای کامپایل و بسته‌بندی برنامه را توصیف می‌کند. هر Build Type مجموعه‌ای نام‌گذاری شده از گزینه‌هاست: debuggable (فعال کردن دیباگ)، minificationEnabled (فعال کردن فشرده‌سازی کد)، shrinkResources (فعال کردن فشرده‌سازی منابع)، proguardFiles (فایل‌های قوانین ProGuard)، signingConfig (گواهی امضا) و موارد دیگر. Build Types در بلوک android.buildTypes فایل build.gradle ماژول app اعلام می‌شوند.

وظیفه اصلی Build Type جداسازی development workflow (ساخت سریع، لاگ‌های دقیق، دیباگ) و production release (کد بهینه‌شده، حداقل اندازه، امنیت) است. نسخه debug باید در چند ثانیه ساخته شود و حداکثر اطلاعات را به توسعه‌دهنده ارائه دهد. نسخه release باید برای کاربران حداکثر سرعت و فشردگی را داشته باشد. Build Type یک پیکربندی زیرساختی است که به عملکرد برنامه مرتبط نیست.

Android Gradle Plugin به طور خودکار برای هر Build Type source set ایجاد می‌کند — دایرکتوری src/<buildType>/ (مثلاً src/debug/، src/release/). در این source set می‌توان منابع، کد و مانیفستی را قرار داد که فقط برای آن نوع ساخت اعمال شوند. مثلاً در src/debug/ می‌توان AndroidManifest.xml با مجوز نصب از ADB قرار داد و در src/release/ بدون آن. Source set Build Type بر source set Product Flavor اولویت دارد.

Build Type در مقابل Product Flavor

تفاوت کلیدی: Build Type به سوال «چگونه بسازیم؟» پاسخ می‌دهد و Product Flavor به سوال «چه چیزی بسازیم؟». Build Type می‌تواند debug، release، staging باشد. Product Flavor می‌تواند free، paid، enterprise باشد. Build Type عملکرد برنامه را تغییر نمی‌دهد (صفحه‌ای اضافه یا حذف نمی‌کند)، Product Flavor تغییر می‌دهد. Build Type می‌تواند دیباگر را غیرفعال و ابهام‌سازی را فعال کند، Product Flavor می‌تواند applicationId و منابع را تغییر دهد. هر دو به صورت جفت کار می‌کنند: هر Build Type با هر Product Flavor ترکیب می‌شود و Build Variant را تشکیل می‌دهد.

Build Types استاندارد: debug و release

Debug Build Typeای است که به طور پیش‌فرض توسط AGP ایجاد می‌شود.它包括 debuggable=true، که امکان اتصال دیباگر، مشاهده لاگ‌های Log.d و استفاده از پروفایلر Android Studio را فراهم می‌کند. Minification غیرفعال است، بنابراین ساخت سریع انجام می‌شود. در نسخه debug، applicationId پسوند «.debug» را دریافت می‌کند (اگر بازنویسی نشده باشد)، که امکان نصب نسخه debug را به همراه نسخه release روی یک دستگاه فراهم می‌کند. نسخه debug با گواهینامه debug.keystore امضا می‌شود که به طور خودکار توسط Android SDK ایجاد می‌شود.

Release Build Type برای انتشار برنامه است. debuggable=false، minificationEnabled=true (پیش‌فرض)، shrinkResources=true. توسعه‌دهنده باید signingConfig را با گواهی production مشخص کند — در غیر این صورت نسخه release محسوب نمی‌شود. Release از ProGuard یا R8 برای ابهام‌سازی، بهینه‌سازی و فشرده‌سازی کد استفاده می‌کند. Android Studio نمی‌تواند به نسخه release دیباگر متصل کند (اگر debuggable=false). تمام فراخوانی‌های Log.d و Log.v در مرحله minification از کد حذف می‌شوند، اگر قوانین ProGuard مربوطه پیکربندی شده باشند.

مهم: نسخه‌های debug رفتار release را تست نمی‌کنند. Minification می‌تواند رفتار کد را تغییر دهد — reflection، سریال‌سازی، Gson/SQLite و سایر کتابخانه‌ها اغلب به قوانین ProGuard نیاز دارند. بنابراین قبل از انتشار حتماً نسخه release را ساخته و تست کنید. Google Play Console و Firebase Test Lab امکان آپلود نسخه‌های release برای تست خودکار روی دستگاه‌های واقعی قبل از انتشار را فراهم می‌کنند.

groovy
android {
    buildTypes {
        debug {
            debuggable true
            minification false
            signingConfig signingConfigs.debug
            versionNameSuffix "-debug"
        }

        release {
            debuggable false
            minification true
            shrinkResources true
            proguardFiles "proguard-rules.pro"
            signingConfig signingConfigs.release
            ndk { abiFilters "arm64-v8a", "x86_64" }
        }
    }
}

ایجاد Build Types سفارشی

ارث‌بری از طریق initWith

علاوه بر debug و release می‌توان Build Types سفارشی ایجاد کرد — مثلاً staging (محیط میانی) یا benchmark (برای تست‌های عملکرد). Build Type سفارشی در بلوک buildTypes مانند debug و release اعلام می‌شود. نام می‌تواند دلخواه باشد، اما توصیه می‌شود از نام‌های معنادار به زبان انگلیسی استفاده شود. برای staging معمولاً debuggable=true (برای تشخیص مشکلات در محیط staging) و minification=true (برای تست ابهام‌سازی قبل از production) تنظیم می‌شود.

Build Type سفارشی به طور خودکار source set مربوطه (src/staging/) را دریافت می‌کند و وظایفی مانند assembleStaging تولید می‌کند. AGP محدودیتی برای تعداد انواع سفارشی اعمال نمی‌کند، اما هر نوع جدید تعداد Build Variants را چند برابر می‌کند. حد عملی 4-5 Build Types است: debug، staging، benchmark، release و احتمالاً debugMinified (debug با minification فعال برای تست قوانین ProGuard).

برای Build Type سفارشی می‌توان debuggable را از debug با استفاده از initWith به ارث برد. کلمه کلیدی initWith تمام پارامترهای Build Type مشخص شده را کپی می‌کند و سپس می‌توان آنها را بازنویسی کرد. این برای ایجاد staging بر اساس debug راحت است: initWith debug + فعال کردن minification. بدون initWith باید تمام پارامترهای نوع پایه را به صورت دستی فهرست کرد.

groovy
android {
    buildTypes {
        staging {
            initWith debug
            minification true
            shrinkResources true
            proguardFiles "staging-proguard-rules.pro"
            versionNameSuffix "-staging"
        }

        benchmark {
            initWith release
            signingConfig signingConfigs.debug
            matchingFallbacks = ["release"]
        }
    }
}

// matchingFallbacks — برای کتابخانه‌هایی که نوع benchmark ندارند
// اگر کتابخانه فقط release دارد — AGP از آن استفاده می‌کند

پیکربندی امضا برای انواع مختلف ساخت

SigningConfig تعیین می‌کند که APK یا AAB با چه گواهی امضا می‌شود. Android امضای همه برنامه‌های قابل نصب را الزامی می‌کند — بدون آن سیستم اجازه نصب APK را نمی‌دهد. برای نسخه‌های debug، AGP از debug.keystore استفاده می‌کند — گواهی از پیش نصب شده با رمز عبور مشخص که توسط Android SDK Tools تولید می‌شود. برای نسخه‌های release باید گواهی خود را از طریق Android Studio (Build → Generate Signed Bundle/APK) یا با دستور keytool ایجاد کنید.

ذخیره کلیدهای امضا یک جنبه حیاتی امنیتی است. توصیه می‌شود کلیدهای release را در مخزن کد منبع ذخیره نکنید. در عوض از موارد زیر استفاده می‌شود: فایل keystore.properties (اضافه شده به .gitignore)، متغیرهای محیطی CI/CD یا ذخیره‌گاه رمزگذاری شده Android Studio. در CI/CD (GitHub Actions، GitLab CI) کلیدهای امضا در secrets ذخیره شده و از طریق ویژگی‌های سیستمی به build.gradle منتقل می‌شوند. مثال: storePassword = System.getenv("KEYSTORE_PASSWORD").

هر Build Type می‌تواند به signingConfig خود ارجاع دهد. برای release — گواهی production، برای debug — debug.keystore، برای staging — گواهی staging جداگانه. پیکربندی امضا مستقیماً بر امکان نصب برنامه تأثیر می‌گذارد: اگر debug با debug.keystore و staging با کلید production امضا شود، staging به دلیل عدم تطابق امضا نمی‌تواند روی نسخه debug نصب شود. ApplicationId نیز باید متفاوت باشد — برای این منظور از applicationIdSuffix استفاده می‌شود.

groovy
android {
    signingConfigs {
        debug {
            storeFile file("debug.keystore")
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
        release {
            storeFile file("release-key.jks")
            storePassword System.getenv("KEYSTORE_PASS")
            keyAlias "my-key"
            keyPassword System.getenv("KEY_PASS")
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

Minification، ProGuard و R8

Resource Shrinking

Minification فرآیند حذف کدهای استفاده نشده و تغییر نام کلاس‌ها، متدها و فیلدها به نام‌های کوتاه است. AGP minification را با استفاده از ProGuard (قدیمی) یا R8 (توصیه شده، از نسخه 3.4 AGP داخلی) انجام می‌دهد. R8 چهار عملیات انجام می‌دهد: shrinking (حذف کلاس‌های استفاده نشده)، optimisation (ساده‌سازی کد)، obfuscation (تغییر نام) و preverify (افزودن اطلاعات سازگاری). نتیجه — APK با اندازه کوچکتر که decompile کردن آن دشوارتر است.

قوانین minification در ProGuard rules files تعریف می‌شوند — فایل‌های متنی با سینتکس -keep، -dontwarn، -keepclassmembers. بدون قوانین، R8 کلاس‌هایی را که از طریق reflection (Gson، Retrofit، Room، Kotlin serialization) استفاده می‌شوند حذف یا تغییر نام می‌دهد. الگوی پروژه Android Studio proguard-rules.pro ایجاد می‌کند که قوانین کتابخانه‌های خاص به آن اضافه می‌شود. کتابخانه‌ها همچنین می‌توانند قوانین داخلی داشته باشند — آنها به طور خودکار از jar/aar متصل می‌شوند.

Shrink resources (shrinkResources=true) منابع استفاده نشده را از APK حذف می‌کند. R8 ابتدا تعیین می‌کند کدام منابع در کد استفاده نمی‌شوند (R.java و ارجاعات در مانیفست را بررسی می‌کند) و سپس آنها را از نسخه نهایی حذف می‌کند. برای منابعی که از طریق getIdentifier() یا کتابخانه‌های شخص ثالث استفاده می‌شوند، باید tools:keep="@layout/my_layout" را به منابع اضافه کرد. در ترکیب با minification، resource shrinking می‌تواند اندازه APK را 40-60% کاهش دهد.

text
# proguard-rules.pro — قوانین اجباری
# Gson: کلاس‌ها را برای سریال‌سازی حفظ کنید
-keepclassmembers class com.example.** {
    <fields>;
}

# Retrofit: رابط‌های API را حفظ کنید
-keep,allowobfuscation interface com.example.api.*

# Room: DAO و Entity را حفظ کنید
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }

# Kotlin Coroutines: جلوگیری از حذف Continuation
-keepnames class kotlinx.coroutines.internal.*

# OkHttp: حفظ service loader
-keep class okhttp3.** { *; }

BuildConfigField و منابع برای Build Type

BuildConfig یک کلاس Java/Kotlin است که به طور خودکار تولید می‌شود و شامل ثابت‌های تعریف شده در defaultConfig، productFlavors و buildTypes است. از طریق buildConfigField می‌توان فیلدهای سفارشی اضافه کرد: buildConfigField "String", "API_URL", '"https://api.example.com"'. BuildConfigField اعلام شده در buildType در تمام variant‌های این type در دسترس است. مقادیر موجود در buildType مقادیر productFlavor را که به نوبه خود defaultConfig را بازنویسی می‌کنند، لغو می‌کنند.

برای نسخه‌های debug راحت است API_URL را روی localhost یا سرور staging و برای release روی production تنظیم کنید. BuildConfig.FLAVOR و BuildConfig.BUILD_TYPE نیز به طور خودکار تولید می‌شوند و نام flavor و build type جاری را شامل می‌شوند. در کد می‌توان استفاده کرد: if (BuildConfig.DEBUG) { /* لاگ‌ها */ } — ثابت DEBUG فقط برای build type debug برابر true است. BuildConfig.DEBUG یک فیلد استاندارد است که AGP به هر BuildConfig اضافه می‌کند.

منابع Build Type از طریق source set src/<buildType>/res/ تعریف می‌شوند. مثلاً src/debug/res/values/strings.xml می‌تواند متن «Server: Dev» را داشته باشد و src/release/res/ — «Server: Prod». منابع مانیفست نیز از طریق source set بازنویسی می‌شوند: src/debug/AndroidManifest.xml می‌تواند فقط برای نسخه‌های debug شامل <uses-permission android:name="android.permission.INTERNET" /> باشد. این تمیزتر از بررسی BuildConfig در کد است و حتی برای ویژگی‌هایی که نمی‌توان به صورت برنامه‌نویسی تنظیم کرد (مثلاً networkSecurityConfig) کار می‌کند.

kotlin
// src/debug/kotlin/.../DebugConfig.kt
object DebugConfig {
    val apiUrl = "http://localhost:8080/api"
    val enableLogging = true
    val enableCrashReporting = false
}

// src/release/kotlin/.../ReleaseConfig.kt
object ReleaseConfig {
    val apiUrl = "https://api.production.com/v2"
    val enableLogging = false
    val enableCrashReporting = true
}

// استفاده: کلاس اصلی Config را از طریق reflection بارگیری می‌کند
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
    "debug" -> DebugConfig
    else -> ReleaseConfig
}

سوالات متداول

آیا می‌توان نسخه debug با minification داشت؟

بله، یک Build Type سفارشی مانند debugMinified با initWith debug ایجاد کنید و minification را فعال کنید: debugMinified { initWith debug; minification true }. این برای تست قوانین ProGuard بدون ساخت نسخه کامل release مفید است.

چگونه بررسی کنیم که نسخه release به درستی امضا شده است؟

apksigner را از Android SDK اجرا کنید: apksigner verify --print-certs app-release.apk. اگر گواهی با گواهی آپلود شده در Google Play Console مطابقت داشته باشد — امضا صحیح است. همچنین می‌توان از طریق jarsigner برای فرمت‌های قدیمی بررسی کرد.

matchingFallbacks در Build Type چیست؟

matchingFallbacks مشخص می‌کند اگر کتابخانه نوع مورد نیاز را نداشته باشد از کدام Build Type استفاده شود. مثلاً اگر برنامه نوع «staging» دارد و کتابخانه فقط «release» را دارد، AGP از release برای کتابخانه استفاده می‌کند. به صورت لیست مشخص می‌شود: matchingFallbacks = ["release", "debug"].

چگونه minification را برای یک کتابخانه خاص غیرفعال کنیم؟

در قوانین ProGuard از -keep برای کلاس‌های کتابخانه استفاده کنید. مثال: -keep class com.some.library.** { *; }. برای غیرفعال کردن کامل minification برای همه کتابخانه‌ها، -dontobfuscate و -dontoptimize را در proguard-rules.pro تنظیم کنید.

آیا Build Type بر نسخه API Android تأثیر می‌گذارد؟

Build Type به خودی خود minSdk یا targetSdk را تغییر نمی‌دهد. اما می‌توان minSdk را برای Build Type خاص تنظیم کرد: debug { minSdk 21 }. این برای نسخه‌های debug مفید است — می‌توان فقط API 21+ را برای سرعت بخشیدن به ساخت پشتیبانی کرد، در حالی که release روی minSdk 26 ساخته می‌شود.

خلاصه

  • Build Type — پیکربندی زیرساختی ساخت که دیباگ، فشرده‌سازی و امضا را تعیین می‌کند.
  • Debug — ساخت سریع برای توسعه، release — بهینه‌شده برای انتشار.
  • Build Types سفارشی (staging, benchmark) از طریق initWith برای ارث‌بری پارامترها ایجاد می‌شوند.
  • R8 minification، obfuscation و resource shrinking را انجام می‌دهد و APK را تا 60% کاهش می‌دهد.
  • BuildConfigField و source sets امکان تعریف متغیرها و منابع را برای هر نوع فراهم می‌کنند.
  • کلیدهای امضا برای release باید خارج از مخزن — در CI/CD secrets یا ذخیره‌گاه رمزگذاری شده نگهداری شوند.
  • توصیه: همیشه قبل از انتشار نسخه release را تست کنید — debug رفتار با minification را نشان نمی‌دهد.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید