Build Type في تطوير Android هو تكوين Gradle الذي يحدد كيفية بناء التطبيق: مع التصحيح أو بدونه، مع تحسين الكود أو بدونه، وبأي شهادة توقيع. يوفر Android Gradle Plugin نوعين قياسيين من Build Type — debug و release، ويمكن للمطور إضافة أنواع مخصصة مثل staging أو benchmark. وفقًا لـ Google Android Developers، 2025، فإن التكوين الصحيح لـ Build Type يقلل حجم APK بنسبة تصل إلى 60% بفضل التصغير وضغط الموارد. يتم دمج كل Build Type مع Product Flavors لتكوين Build Variant.
الرئيسية
Build Type هو عنصر من تكوين Gradle في مشاريع Android يصف معلمات التجميع والتغليف للتطبيق. كل Build Type هو مجموعة مسماة من الخيارات: debuggable (تمكين التصحيح)، minificationEnabled (تمكين ضغط الكود)، shrinkResources (تمكين ضغط الموارد)، proguardFiles (ملفات قواعد ProGuard)، signingConfig (شهادة التوقيع) وغيرها. يتم تعريف Build Types في كتلة android.buildTypes في ملف build.gradle لوحدة app.
المهمة الرئيسية لـ Build Type هي فصل سير عمل التطوير (بناء سريع، سجلات مفصلة، تصحيح) عن الإصدار الإنتاجي (كود محسن، حجم أدنى، أمان). يجب أن يتم بناء debug في ثوانٍ ويوفر أقصى قدر من المعلومات للمطور. يجب أن يكون بناء release سريعًا ومضغوطًا قدر الإمكان للمستخدمين. Build Type هو إعداد بنية تحتية، غير مرتبط بوظائف التطبيق.
يقوم Android Gradle Plugin تلقائيًا بإنشاء مجموعة مصادر لكل Build Type — الدليل src/<buildType>/ (مثل src/debug/، src/release/). يتم تطبيق الموارد والكود وملفات البيان الموضوعة في مجموعة المصادر هذه فقط على ذلك النوع من البناء. على سبيل المثال، يمكن وضع AndroidManifest.xml في src/debug/ مع إذن التثبيت من ADB، وبدونه في src/release/. مجموعة مصادر 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.
Debug هو Build Type الافتراضي الذي ينشئه AGP. يحتوي على debuggable=true، مما يسمح بتوصيل المصحح وعرض سجلات Log.d واستخدام ملف تعريف Android Studio. التصغير معطل، لذا يكون البناء سريعًا. في بناء debug، يحصل applicationId على اللاحقة ".debug" (إذا لم يتم تجاوزها)، مما يسمح بتثبيت إصدار debug جنبًا إلى جنب مع إصدار release على نفس الجهاز. يتم توقيع بناء debug بشهادة من debug.keystore، التي ينشئها Android SDK تلقائيًا.
Release هو Build Type لنشر التطبيق. debuggable=false، minificationEnabled=true (افتراضيًا)، shrinkResources=true. يجب على المطور تحديد signingConfig بشهادة إنتاج — وإلا فلن يعتبر البناء إصدارًا release. يستخدم بناء release ProGuard أو R8 للتشويش والتحسين وضغط الكود. لا يمكن لـ Android Studio توصيل المصحح ببناء release (إذا كان debuggable=false). تتم إزالة جميع استدعاءات Log.d و Log.v من الكود أثناء التصغير إذا تم تكوين قواعد ProGuard المناسبة.
هام: بنيات debug لا تختبر سلوك release. يمكن للتصغير تغيير سلوك الكود — الانعكاس والتسلسل و Gson/SQLite والمكتبات الأخرى غالبًا ما تتطلب قواعد ProGuard. لذلك، قم دائمًا ببناء واختبار بناء release قبل النشر. تسمح Google Play Console و Firebase Test Lab بتحميل بنيات release للاختبار التلقائي على أجهزة حقيقية قبل النشر.
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" }
}
}
}
بالإضافة إلى debug و release، يمكن إنشاء Build Types مخصصة — مثل staging (بيئة وسيطة) أو benchmark (لاختبارات الأداء). يتم تعريف Build Type مخصص في كتلة buildTypes بنفس طريقة debug و release. يمكن أن يكون الاسم أي شيء، لكن يُنصح باستخدام أسماء واضحة دلاليًا بالإنجليزية. بالنسبة لـ staging، عادةً ما يتم تعيين debuggable=true (لتشخيص المشكلات في بيئة staging) و minification=true (لاختبار التشويش قبل الإنتاج).
يحصل Build Type المخصص تلقائيًا على مجموعة مصادر مقابلة (src/staging/) ويولد مهام مثل assembleStaging. لا يفرض AGP قيودًا على عدد الأنواع المخصصة، لكن كل نوع جديد يضاعف عدد Build Variants. الحد العملي هو 4-5 Build Types: debug، staging، benchmark، release، وربما debugMinified (debug مع تفعيل التصغير لاختبار قواعد ProGuard).
بالنسبة لـ Build Type مخصص، يمكنك وراثة debuggable من debug باستخدام initWith. تنسخ الكلمة الأساسية initWith جميع معلمات Build Type المحدد، وبعد ذلك يمكن تجاوزها. هذا مناسب لإنشاء staging بناءً على debug: initWith debug + تفعيل التصغير إضافيًا. بدون initWith، سيكون عليك سرد جميع معلمات النوع الأساسي يدويًا.
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 توقيع جميع التطبيقات القابلة للتثبيت — بدونها لن يسمح النظام بالتثبيت. بالنسبة لبنيات 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 — شهادة إنتاج، لـ debug — debug.keystore، لـ staging — شهادة staging منفصلة. يؤثر تكوين التوقيع مباشرة على إمكانية تثبيت التطبيق: إذا قمت بتوقيع debug بـ debug.keystore و staging بمفتاح إنتاج، فلن يمكن تثبيت staging فوق إصدار debug بسبب عدم تطابق التوقيعات. يجب أن يختلف applicationId أيضًا — استخدم applicationIdSuffix لهذا الغرض.
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
}
}
}
التصغير هو عملية إزالة الكود غير المستخدم وإعادة تسمية الفئات والطرق والحقول إلى أسماء قصيرة. يقوم AGP بالتصغير باستخدام ProGuard (قديم) أو R8 (موصى به، مدمج في AGP بدءًا من الإصدار 3.4). يقوم R8 بأربع عمليات: shrinking (إزالة الفئات غير المستخدمة)، optimization (تبسيط الكود)، obfuscation (إعادة التسمية)، و preverify (إضافة معلومات التوافق). النتيجة هي APK أصغر حجمًا ويصعب فك ترجمته.
يتم تعريف قواعد التصغير في ملفات قواعد ProGuard — ملفات نصية بتركيب مثل -keep، -dontwarn، -keepclassmembers. بدون قواعد، سيزيل R8 أو يعيد تسمية الفئات المستخدمة عبر الانعكاس (Gson، Retrofit، Room، تسلسل Kotlin). ينشئ قالب مشروع Android Studio ملف proguard-rules.pro حيث تضاف القواعد للمكتبات المحددة. قد تحتوي المكتبات أيضًا على قواعد مدمجة — يتم تضمينها تلقائيًا من jar/aar.
ضغط الموارد (shrinkResources=true) يزيل الموارد غير المستخدمة من APK. يحدد R8 أولاً الموارد غير المستخدمة في الكود (يتحقق من R.java ومراجع البيان)، ثم يزيلها من البناء النهائي. بالنسبة للموارد المستخدمة عبر getIdentifier() أو بواسطة مكتبات خارجية، يجب إضافة tools:keep="@layout/my_layout" في الموارد. بالتزامن مع التصغير، يمكن لضغط الموارد تقليل حجم APK بنسبة 40-60%.
# 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.** { *; }
BuildConfig هو فئة Java/Kotlin يتم إنشاؤها تلقائيًا وتحتوي على ثوابت معرفة في defaultConfig و productFlavors و buildTypes. من خلال buildConfigField يمكن إضافة حقول مخصصة: buildConfigField "String"، "API_URL"، '"https://api.example.com"'. BuildConfigField المعلن في buildType متاح في جميع متغيرات هذا النوع. القيم في buildType تتجاوز القيم من productFlavor، التي بدورها تتجاوز defaultConfig.
بالنسبة لبنيات debug، من المناسب تعيين API_URL إلى localhost أو خادم staging، ولـ release إلى الإنتاج. يتم أيضًا إنشاء BuildConfig.FLAVOR و BuildConfig.BUILD_TYPE تلقائيًا ويحتويان على اسم flavor و build type الحاليين. يمكن استخدامه في الكود: if (BuildConfig.DEBUG) { /* سجلات */ } — الثابت DEBUG صحيح فقط لنوع build type debug. BuildConfig.DEBUG هو حقل قياسي يضيفه AGP إلى كل BuildConfig.
يتم تعريف الموارد لـ Build Type عبر مجموعة المصادر src/<buildType>/res/. على سبيل المثال، يمكن أن يحتوي src/debug/res/values/strings.xml على السلسلة "Server: Dev"، بينما src/release/res/ على "Server: Prod". يتم أيضًا تجاوز موارد البيان عبر مجموعة المصادر: يمكن أن يتضمن src/debug/AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET" /> فقط لبنيات debug. هذا أنظف من التحقق من BuildConfig في الكود ويعمل حتى للسمات التي لا يمكن تعيينها برمجيًا (مثل networkSecurityConfig).
// 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 عبر الانعكاس
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
"debug" -> DebugConfig
else -> ReleaseConfig
}
الأسئلة الشائعة
نعم، أنشئ Build Type مخصصًا مثل debugMinified مع initWith debug وقم بتفعيل التصغير: debugMinified { initWith debug; minification true }. هذا مفيد لاختبار قواعد ProGuard بدون بناء إصدار release كامل.
قم بتشغيل apksigner من Android SDK: apksigner verify --print-certs app-release.apk. إذا تطابقت الشهادة مع تلك المرفوعة إلى Google Play Console، فإن التوقيع صحيح. يمكنك أيضًا التحقق باستخدام jarsigner للصيغ القديمة.
matchingFallbacks يحدد أي Build Type من مكتبة يجب استخدامه إذا لم يكن لديها النوع المطلوب. على سبيل المثال، إذا كان للتطبيق نوع "staging" ولكن المكتبة لديها فقط "release"، يستخدم AGP release للمكتبة. يتم تحديده كقائمة: matchingFallbacks = ["release"، "debug"].
في قواعد ProGuard، استخدم -keep لفئات المكتبة. على سبيل المثال: -keep class com.some.library.** { *; }. لتعطيل التصغير تمامًا لجميع المكتبات، حدد -dontobfuscate و -dontoptimize في proguard-rules.pro.
Build Type في حد ذاته لا يغير minSdk أو targetSdk. ومع ذلك، يمكنك تعيين minSdk لـ Build Type محدد: debug { minSdk 21 }. هذا مفيد لبنيات debug — يمكنك دعم API 21+ فقط لتسريع البناء، بينما تستخدم بنيات release minSdk 26.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.