Build Type — là gì, cấu hình debug và release trong Gradle

Tác giả: IT Sectr Đã đăng: 2026-05-30 Thời gian đọc: 9 phút

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 — cấu hình xây dựng với các tham số debuggable, minification, signing.
  • Debug — bản dựng gỡ lỗi với debuggable=true, minification=false, debug.keystore.
  • Release — bản dựng cuối cùng với debuggable=false, minification=true, chữ ký sản xuất.
  • ProGuard và R8 thực hiện làm rối, tối ưu hóa và nén mã trong các bản dựng release.
  • BuildConfigField cho phép đặt các biến có thể truy cập trong mã, riêng biệt cho từng loại.

Build Type là gì?

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.

Build Type so với 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.

Build Types tiêu chuẩn: debug và release

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.

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" }
        }
    }
}

Tạo Build Types tùy chỉnh

Kế thừa qua initWith

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.

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 — 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ó

Cấu hình ký cho các loại bản dựng khác nhau

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.

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 và R8

Resource Shrinking

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%.

text
# 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.** { *; }

BuildConfigField và tài nguyên cho Build Type

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).

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
}

// 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

Tôi có thể có bản dựng debug với minification không?

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 đủ.

Làm thế nào để xác minh bản dựng release được ký đúng?

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 trong Build Type là gì?

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"].

Làm thế nào để tắt minification cho một thư viện cụ thể?

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-dontoptimize trong proguard-rules.pro.

Build Type có ảnh hưởng đến phiên bản API Android không?

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

  • Build Type — cấu hình cơ sở hạ tầng xây dựng xác định gỡ lỗi, nén và ký.
  • Debug — bản dựng nhanh cho phát triển, release — tối ưu hóa cho xuất bản.
  • Build Types tùy chỉnh (staging, benchmark) được tạo qua initWith để kế thừa tham số.
  • R8 thực hiện minification, làm rối và resource shrinking, giảm APK tới 60%.
  • BuildConfigFieldsource sets cho phép đặt biến và tài nguyên cho từng loại.
  • Khóa ký cho release nên được lưu trữ bên ngoài kho mã — trong CI/CD secrets hoặc bộ nhớ mã hóa.
  • Khuyến nghị: luôn kiểm tra bản dựng release trước khi xuất bản — debug không hiển thị hành vi minification.

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.

Thảo luận dự án

Đọc thêm