Build Type trong phát triển Android là một cấu hình Gradle xác định cách ứng dụng được xây dựng: có hay không gỡ lỗi, có hay không tối ưu hóa mã và với chứng chỉ ký nào. Android Gradle Plugin cung cấp hai Build Type tiêu chuẩn — debug và release, và nhà phát triển có thể thêm các loại tùy chỉnh như staging hoặc benchmark. Theo Google Android Developers, 2025, cấu hình Build Type đúng đắn giúp giảm kích thước APK tới 60% nhờ minification và resource shrinking. Mỗi Build Type được kết hợp với Product Flavors để tạo thành Build Variant.
Những điểm chính
Build Type là một phần tử của cấu hình Gradle trong các dự án Android mô tả các tham số biên dịch và đóng gói của ứng dụng. Mỗi Build Type là một tập hợp các tùy chọn có tên: debuggable (bật gỡ lỗi), minificationEnabled (bật nén mã), shrinkResources (bật nén tài nguyên), proguardFiles (tệp quy tắc ProGuard), signingConfig (chứng chỉ ký) và các tùy chọn khác. Build Types được khai báo trong khối android.buildTypes của tệp build.gradle của mô-đun app.
Nhiệm vụ chính của Build Type là tách biệt quy trình phát triển (xây dựng nhanh, nhật ký chi tiết, gỡ lỗi) khỏi bản phát hành sản xuất (mã được tối ưu hóa, kích thước tối thiểu, bảo mật). Bản dựng debug phải biên dịch trong vài giây và cung cấp tối đa thông tin cho nhà phát triển. Bản dựng release phải nhanh và nhỏ gọn nhất có thể cho người dùng. Build Type là một cài đặt cơ sở hạ tầng, không liên quan đến chức năng của ứng dụng.
Android Gradle Plugin tự động tạo một source set cho mỗi Build Type — thư mục src/<buildType>/ (ví dụ: src/debug/, src/release/). Các tài nguyên, mã và tệp kê khai được đặt trong source set này chỉ áp dụng cho loại bản dựng đó. Ví dụ, src/debug/ có thể chứa AndroidManifest.xml có quyền cài đặt từ ADB, còn src/release/ thì không. Source set của Build Type có quyền ưu tiên hơn source set của Product Flavor.
Sự khác biệt chính: Build Type trả lời câu hỏi "xây dựng như thế nào?", trong khi Product Flavor trả lời "xây dựng cái gì?". Build Type có thể là debug, release, staging. Product Flavor có thể là free, paid, enterprise. Build Type không thay đổi chức năng của ứng dụng (không thêm hoặc xóa màn hình), Product Flavor thì có. Build Type có thể tắt trình gỡ lỗi và bật làm rối, Product Flavor có thể thay đổi applicationId và tài nguyên. Cả hai hoạt động cùng nhau: mỗi Build Type được kết hợp với mỗi Product Flavor để tạo thành Build Variant.
Debug là Build Type được AGP tạo theo mặc định. Nó có debuggable=true, cho phép đính kèm trình gỡ lỗi, xem nhật ký Log.d và sử dụng trình phân tích Android Studio. Minification bị tắt, do đó bản dựng nhanh. Trong bản dựng debug, applicationId nhận hậu tố ".debug" (nếu không bị ghi đè), cho phép cài đặt phiên bản debug song song với phiên bản release trên cùng một thiết bị. Bản dựng debug được ký bằng chứng chỉ từ debug.keystore, được Android SDK tự động tạo.
Release là Build Type để xuất bản ứng dụng. debuggable=false, minificationEnabled=true (mặc định), shrinkResources=true. Nhà phát triển phải chỉ định signingConfig với chứng chỉ sản xuất — nếu không, bản dựng sẽ không được coi là bản dựng release. Bản dựng release sử dụng ProGuard hoặc R8 để làm rối, tối ưu hóa và nén mã. Android Studio không thể đính kèm trình gỡ lỗi vào bản dựng release (nếu debuggable=false). Tất cả các lệnh gọi Log.d và Log.v bị xóa khỏi mã trong quá trình minification nếu các quy tắc ProGuard thích hợp được cấu hình.
Quan trọng: bản dựng debug không kiểm tra hành vi của release. Minification có thể thay đổi hành vi mã — reflection, tuần tự hóa, Gson/SQLite và các thư viện khác thường yêu cầu quy tắc ProGuard. Do đó, hãy luôn xây dựng và kiểm tra bản dựng release trước khi xuất bản. Google Play Console và Firebase Test Lab cho phép tải lên các bản dựng release để kiểm tra tự động trên các thiết bị thực trước khi xuất bản.
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" }
}
}
}
Ngoài debug và release, có thể tạo các Build Types tùy chỉnh — ví dụ staging (môi trường trung gian) hoặc benchmark (để kiểm tra hiệu năng). Một Build Type tùy chỉnh được khai báo trong khối buildTypes giống như debug và release. Tên có thể là bất kỳ, nhưng nên sử dụng tên có ngữ nghĩa rõ ràng bằng tiếng Anh. Đối với staging, thường đặt debuggable=true (để chẩn đoán sự cố trong môi trường staging) và minification=true (để kiểm tra làm rối trước khi sản xuất).
Một Build Type tùy chỉnh tự động nhận được source set tương ứng (src/staging/) và tạo các tác vụ như assembleStaging. AGP không áp đặt giới hạn về số lượng loại tùy chỉnh, nhưng mỗi loại mới nhân lên số lượng Build Variants. Giới hạn thực tế là 4-5 Build Types: debug, staging, benchmark, release và có thể là debugMinified (debug với minification được bật để kiểm tra quy tắc ProGuard).
Đối với Build Type tùy chỉnh, bạn có thể kế thừa debuggable từ debug bằng initWith. Từ khóa initWith sao chép tất cả các tham số của Build Type được chỉ định, sau đó chúng có thể được ghi đè. Điều này thuận tiện để tạo staging dựa trên debug: initWith debug + thêm minification. Nếu không có initWith, bạn phải liệt kê thủ công tất cả các tham số của loại cơ bản.
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 — cho các thư viện không có loại benchmark
// nếu thư viện chỉ có release — AGP sử dụng nó
SigningConfig xác định chứng chỉ nào được sử dụng để ký APK hoặc AAB. Android yêu cầu tất cả các ứng dụng có thể cài đặt phải được ký — nếu không, hệ thống sẽ không cho phép cài đặt. Đối với bản dựng debug, AGP sử dụng debug.keystore — một chứng chỉ được cài đặt sẵn với mật khẩu đã biết do Android SDK Tools tạo ra. Đối với bản dựng release, bạn phải tạo chứng chỉ riêng thông qua Android Studio (Build → Generate Signed Bundle/APK) hoặc qua dòng lệnh keytool.
Lưu trữ khóa ký là một khía cạnh bảo mật quan trọng. Khuyến nghị không lưu trữ khóa release trong kho mã nguồn. Thay vào đó, hãy sử dụng tệp keystore.properties (được thêm vào .gitignore), biến môi trường CI/CD hoặc bộ nhớ được mã hóa của Android Studio. Trong CI/CD (GitHub Actions, GitLab CI), khóa ký được lưu trữ trong secrets và truyền đến build.gradle thông qua thuộc tính hệ thống. Ví dụ: storePassword = System.getenv("KEYSTORE_PASSWORD").
Mỗi Build Type có thể tham chiếu đến signingConfig riêng. Đối với release — chứng chỉ sản xuất, cho debug — debug.keystore, cho staging — chứng chỉ staging riêng biệt. Cấu hình ký ảnh hưởng trực tiếp đến khả năng cài đặt ứng dụng: nếu bạn ký debug bằng debug.keystore và staging bằng khóa sản xuất, staging không thể được cài đặt chồng lên phiên bản debug do chữ ký không khớp. ApplicationId cũng phải khác nhau — sử dụng applicationIdSuffix cho việc này.
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 là quá trình loại bỏ mã không sử dụng và đổi tên các lớp, phương thức và trường thành tên ngắn. AGP thực hiện minification bằng ProGuard (cũ) hoặc R8 (khuyến nghị, được tích hợp trong AGP từ phiên bản 3.4). R8 thực hiện bốn thao tác: shrinking (loại bỏ các lớp không sử dụng), optimisation (đơn giản hóa mã), obfuscation (đổi tên) và preverify (thêm thông tin tương thích). Kết quả là APK nhỏ hơn và khó dịch ngược hơn.
Các quy tắc minification được định nghĩa trong tệp quy tắc ProGuard — các tệp văn bản có cú pháp như -keep, -dontwarn, -keepclassmembers. Nếu không có quy tắc, R8 sẽ xóa hoặc đổi tên các lớp được sử dụng qua reflection (Gson, Retrofit, Room, tuần tự hóa Kotlin). Mẫu dự án Android Studio tạo tệp proguard-rules.pro nơi các quy tắc cho các thư viện cụ thể được thêm vào. Các thư viện cũng có thể chứa quy tắc tích hợp — chúng được tự động bao gồm từ jar/aar.
Shrink resources (shrinkResources=true) loại bỏ các tài nguyên không sử dụng khỏi APK. R8 trước tiên xác định tài nguyên nào không được sử dụng trong mã (kiểm tra R.java và tham chiếu trong tệp kê khai), sau đó loại bỏ chúng khỏi bản dựng cuối cùng. Đối với các tài nguyên được sử dụng qua getIdentifier() hoặc bởi các thư viện bên thứ ba, bạn cần thêm tools:keep="@layout/my_layout" trong tài nguyên. Kết hợp với minification, resource shrinking có thể giảm kích thước APK từ 40-60%.
# proguard-rules.pro — quy tắc bắt buộc
# Gson: giữ lại các lớp để tuần tự hóa
-keepclassmembers class com.example.** {
<fields>;
}
# Retrofit: giữ lại các giao diện API
-keep,allowobfuscation interface com.example.api.*
# Room: giữ lại DAO và Entity
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }
# Kotlin Coroutines: ngăn xóa Continuation
-keepnames class kotlinx.coroutines.internal.*
# OkHttp: bảo toàn service loader
-keep class okhttp3.** { *; }
BuildConfig là một lớp Java/Kotlin được tạo tự động chứa các hằng số được định nghĩa trong defaultConfig, productFlavors và buildTypes. Thông qua buildConfigField, có thể thêm các trường tùy chỉnh: buildConfigField "String", "API_URL", '"https://api.example.com"'. BuildConfigField được khai báo trong buildType có sẵn trong tất cả các biến thể của loại đó. Giá trị trong buildType ghi đè giá trị từ productFlavor, productFlavor ghi đè defaultConfig.
Đối với bản dựng debug, thuận tiện để đặt API_URL thành localhost hoặc máy chủ staging, và cho release — thành sản xuất. BuildConfig.FLAVOR và BuildConfig.BUILD_TYPE cũng được tạo tự động và chứa tên của flavor và build type hiện tại. Trong mã có thể sử dụng: if (BuildConfig.DEBUG) { /* nhật ký */ } — hằng số DEBUG chỉ đúng cho build type debug. BuildConfig.DEBUG là một trường tiêu chuẩn mà AGP thêm vào mọi BuildConfig.
Tài nguyên cho Build Type được định nghĩa qua source set src/<buildType>/res/. Ví dụ, src/debug/res/values/strings.xml có thể chứa chuỗi "Server: Dev", trong khi src/release/res/ có thể chứa "Server: Prod". Tài nguyên tệp kê khai cũng được ghi đè qua source set: src/debug/AndroidManifest.xml có thể bao gồm <uses-permission android:name="android.permission.INTERNET" /> chỉ cho bản dựng debug. Điều này sạch hơn so với kiểm tra BuildConfig trong mã và hoạt động ngay cả với các thuộc tính không thể đặt bằng mã (như 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
}
// Cách dùng: lớp chính tải Config qua reflection
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
"debug" -> DebugConfig
else -> ReleaseConfig
}
Câu hỏi thường gặp
Có, hãy tạo một Build Type tùy chỉnh như debugMinified với initWith debug và bật minification: debugMinified { initWith debug; minification true }. Điều này hữu ích để kiểm tra quy tắc ProGuard mà không cần xây dựng phiên bản release đầy đủ.
Chạy apksigner từ Android SDK: apksigner verify --print-certs app-release.apk. Nếu chứng chỉ khớp với chứng chỉ đã tải lên Google Play Console, chữ ký đúng. Bạn cũng có thể xác minh qua jarsigner cho các định dạng cũ.
matchingFallbacks chỉ định Build Type nào của thư viện sẽ sử dụng nếu thư viện không có loại cần thiết. Ví dụ, nếu ứng dụng có loại "staging" nhưng thư viện chỉ có "release", AGP sử dụng release cho thư viện. Nó được chỉ định dưới dạng danh sách: matchingFallbacks = ["release", "debug"].
Trong quy tắc ProGuard, sử dụng -keep cho các lớp của thư viện. Ví dụ: -keep class com.some.library.** { *; }. Để tắt hoàn toàn minification cho tất cả thư viện, chỉ định -dontobfuscate và -dontoptimize trong proguard-rules.pro.
Build Type tự nó không thay đổi minSdk hay targetSdk. Tuy nhiên, bạn có thể đặt minSdk cho một Build Type cụ thể: debug { minSdk 21 }. Điều này hữu ích cho bản dựng debug — bạn có thể chỉ hỗ trợ API 21+ để tăng tốc độ xây dựng, trong khi bản dựng release sử dụng minSdk 26.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm