build.gradle คือไฟล์บิวด์หลักของโปรเจกต์ Android บน Gradle ที่มีคำแนะนำสำหรับการคอมไพล์ แพ็กเกจ และเซ็นชื่อแอปพลิเคชัน แต่ละโมดูลในโปรเจกต์มี build.gradle ของตัวเอง: หนึ่งรายการในระดับโปรเจกต์ (project-level) และหนึ่งรายการสำหรับแต่ละโมดูล (module-level) ตามข้อมูลจาก Google Android Developers, 2025 การกำหนดค่า build.gradle ที่ถูกต้องช่วยเร่งการบิวด์ได้ถึง 40% และขจัดข้อขัดแย้งของ dependencies ไวยากรณ์รองรับสองภาษา: Groovy (build.gradle) และ Kotlin DSL (build.gradle.kts)
ประเด็นสำคัญ
build.gradle คือสคริปต์บิวด์ที่เขียนด้วยภาษา Groovy (นามสกุล .gradle) หรือ Kotlin (.gradle.kts) ที่จัดการทุกด้านของการคอมไพล์แอปพลิเคชัน Android Gradle คือระบบบิวด์อัตโนมัติที่ Google นำมาใช้ในปี 2013 เป็นมาตรฐานสำหรับ Android build.gradle อธิบายว่า: ปลั๊กอินใดที่ถูกนำมาใช้ (Android, Kotlin, ไลบรารี), dependencies ใดที่เชื่อมต่อ, เวอร์ชัน SDK ใดที่ใช้, วิธีเซ็นชื่อแอปพลิเคชันและเผยแพร่ที่ไหน
กระบวนการบิวด์ประกอบด้วยสามเฟส: Initialization (การค้นหาโมดูล), Configuration (การดำเนินการสคริปต์ build.gradle), Execution (การดำเนินการงาน) build.gradle จะทำงานในช่วงเฟส Configuration เมื่อ Gradle สร้างกราฟงาน ในจุดนี้ Build Variants จะถูกกำหนด, dependencies จะถูกคำนวณ และงานจะถูกกำหนดค่า สิ่งสำคัญ: build.gradle คือโค้ด ไม่ใช่แค่การกำหนดค่า สามารถใช้เงื่อนไข ลูป การเรียกเมธอด และสคริปต์ภายนอกได้
ไฟล์ Gradle จะถูกเก็บไว้ในรูทของโมดูล (app/build.gradle) และรูทของโปรเจกต์ (build.gradle) นอกจากนี้ Gradle รองรับ apply from — การรวมสคริปต์ Gradle ภายนอก ซึ่งช่วยให้สามารถแยกตรรกะที่ซ้ำซ้อนออกไปยังไฟล์ที่มีการตั้งค่าร่วมกัน ด้วยการถือกำเนิดของ Convention Plugins (AGP 7+) ทำให้ apply from ถือว่าล้าสมัย — Convention Plugins มอบวิธีที่ type-safe และประกอบได้สำหรับการใช้การกำหนดค่าซ้ำระหว่างโมดูล
ตั้งแต่ปี 2013 ไวยากรณ์ของ build.gradle มีการเปลี่ยนแปลงครั้งสำคัญ: จาก Groovy ที่มีการกำหนดค่าแบบไดนามิกไปจนถึง Kotlin DSL ที่มีการตรวจสอบขณะคอมไพล์ AGP พัฒนาจากเวอร์ชัน 1.0 ไปเป็น 8.7 (2025) เหตุการณ์สำคัญ: AGP 3.0 (Java 8 desugar, variant API ใหม่), AGP 4.0 (view binding, Java 11), AGP 7.0 (Kotlin DSL เป็นค่าเริ่มต้น, Java 11 ขั้นต่ำ), AGP 8.0 (คลาส R แบบไม่ถ่ายทอด, build config ใน Kotlin), AGP 8.7 (KSP แทน kapt, การกำหนดค่าที่รวดเร็ว)
Project-level build.gradle (รูท) กำหนดปลั๊กอิน repository และการกำหนดค่าที่ใช้ร่วมกันสำหรับทุกโมดูล บล็อกหลัก: plugins (การประกาศปลั๊กอิน Gradle), repositories (แหล่งที่มาของ dependencies: mavenCentral, google, jitpack) โดยปกติ build.gradle ระดับรูทจะไม่มีบล็อก android — จะปรากฏในโมดูล Project-level สามารถมีบล็อก subprojects สำหรับการกำหนดค่าร่วมกันของโปรเจกต์ย่อยทั้งหมด แม้ว่า Convention Plugins จะดีกว่า
Module-level build.gradle (เช่น app/build.gradle) อธิบายโมดูลเฉพาะ หากโมดูลเป็นแอปพลิเคชัน จะใช้ปลั๊กอิน com.android.application หากเป็นไลบรารี — ใช้ com.android.library Module-level ประกอบด้วย: บล็อก android (compileSdk, defaultConfig, buildTypes, productFlavors), บล็อก dependencies (dependencies ของโมดูล) และตัวเลือกบล็อกสำหรับการกำหนดค่าการทดสอบและการแพ็กเกจ Module-level จะทำงานหลังจาก project-level และสามารถแทนที่การตั้งค่าร่วมกันได้
ตั้งแต่ AGP 8.0 เป็นต้นไป build.gradle ระดับรูทสามารถใช้ version catalogs (libs.versions.toml) สำหรับการจัดการเวอร์ชัน dependencies แบบรวมศูนย์ version catalog คือไฟล์ในไดเรกทอรี gradle/ ที่มีเวอร์ชัน ไลบรารี และปลั๊กอิน ใน build.gradle dependencies จะเชื่อมต่อผ่าน libs: implementation(libs.retrofit) version catalogs เป็นสิ่งจำเป็นสำหรับโปรเจกต์ใหม่และแนะนำสำหรับโปรเจกต์ทั้งหมดที่มีสามโมดูลขึ้นไป
// settings.gradle.kts — รากโปรเจกต์
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
// build.gradle.kts (project-level)
plugins {
id("com.android.application") version "8.7.0" apply false
id("org.jetbrains.kotlin.android") version "2.0.21" apply false
}
// app/build.gradle.kts (module-level)
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
}
android {
namespace = "com.example.myapp"
compileSdk = 35
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0.0"
}
}
Groovy คือภาษา JVM แบบไดนามิกที่เป็นไวยากรณ์ดั้งเดิมของ Gradle สคริปต์ Groovy (.gradle) ใช้การพิมพ์แบบไดนามิก: สามารถละเว้นชนิด ใช้สตริงที่มีหรือไม่มีเครื่องหมายคำพูด เรียกเมธอดที่ไม่มีอยู่ในขณะคอมไพล์ ความยืดหยุ่นของ Groovy ก็เป็นข้อเสียเช่นกัน: IDE ไม่สามารถตรวจสอบไวยากรณ์และชนิดได้จนกว่าสคริปต์จะทำงาน ซึ่งนำไปสู่ข้อผิดพลาดขณะรันไทม์เนื่องจากชื่อพารามิเตอร์หรือชนิดที่ไม่ถูกต้อง
Kotlin DSL (.gradle.kts) ใช้การพิมพ์แบบคงที่ของ Kotlin IDE ตรวจสอบชนิด แนะนำพารามิเตอร์ที่มีผ่านการเติมข้อความอัตโนมัติ และเน้นข้อผิดพลาดขณะแก้ไข Kotlin DSL ช้ากว่าในช่วงเฟส Configuration (เนื่องจากการคอมไพล์ไฟล์ .kts เป็นไบต์โค้ด) แต่ Google ปรับปรุงประสิทธิภาพอย่างต่อเนื่อง: AGP 8.5+ ใช้ Gradle Configuration Cache และ Caching Kotlin DSL compilation ซึ่งลดความแตกต่างเหลือ 1-2 วินาที
Google แนะนำ Kotlin DSL สำหรับโปรเจกต์ใหม่ทั้งหมดและการย้ายโปรเจกต์ที่มีอยู่อย่างค่อยเป็นค่อยไป การย้ายจาก Groovy ไป Kotlin DSL ทำได้ตรงไปตรงมา: เครื่องหมายคำพูดถูกแทนที่ด้วยวงเล็บ เพิ่มชนิด ตัวดำเนินการถูกแปลงเป็นฟังก์ชัน ไลบรารีส่วนใหญ่มีตัวอย่าง Kotlin DSL ในเอกสารประกอบ สำหรับกรณีที่ซับซ้อน (Custom Plugin, Task Graph) Kotlin DSL มี API ที่ type-safe และป้องกันข้อผิดพลาดที่ใน Groovy จะถูกค้นพบเฉพาะในรันไทม์ Version catalogs (libs.versions.toml) ทำงานเหมือนกันกับทั้งสองไวยากรณ์
| คุณลักษณะ | Groovy (.gradle) | Kotlin DSL (.gradle.kts) |
|---|---|---|
| การพิมพ์ | ไดนามิก | คงที่ |
| การรองรับ IDE | จำกัด | เต็มรูปแบบ (เติมข้อความอัตโนมัติ, ชนิด) |
| ความเร็วในการกำหนดค่า | เร็วกว่า (ไม่มีการคอมไพล์) | ช้ากว่า (คอมไพล์ .kts) |
| ข้อผิดพลาด | รันไทม์ | ขณะคอมไพล์ |
| คำแนะนำ | เฉพาะโปรเจกต์เก่า | โปรเจกต์ใหม่และการย้าย |
บล็อก android คือองค์ประกอบหลักของ module-level build.gradle ภายในกำหนดค่า: namespace (สำหรับ R และ BuildConfig), compileSdk, defaultConfig, buildTypes, productFlavors, sourceSets, compileOptions, packaging, bundle พารามิเตอร์ทั้งหมดของบล็อก android ใช้ได้เฉพาะกับโมดูล Android เท่านั้น หากโมดูลเป็นไลบรารี จะใช้ปลั๊กอินไลบรารีแทน application และ applicationId จะไม่อยู่ในบล็อก android
compileSdk คือเวอร์ชัน SDK ที่ใช้คอมไพล์โค้ด ควรเป็น Android API ล่าสุด (ในขณะที่เขียน — 35) minSdk คือเวอร์ชัน API ขั้นต่ำที่รองรับ targetSdk คือเวอร์ชันที่แอปพลิเคชันกำหนดเป้าหมาย (การเปลี่ยนแปลงพฤติกรรมของเวอร์ชันนี้จะถูกนำไปใช้) ความแตกต่างระหว่าง compileSdk และ targetSdk: compileSdk กำหนด API ที่มีอยู่ targetSdk กำหนดพฤติกรรมรันไทม์ คำแนะนำ: compileSdk = ล่าสุด, targetSdk = ล่าสุด - 1 (สำหรับการทดสอบการปรับตัวเข้ากับการเปลี่ยนแปลงใหม่)
compileOptions กำหนดความเข้ากันได้ของ Java: sourceCompatibility และ targetCompatibility AGP 8+ ต้องการ Java 17+ สำหรับการคอมไพล์ packaging จัดการการรวมไฟล์จากไลบรารี: exclude, merge, pickFirst สำหรับแก้ไขข้อขัดแย้ง META-INF buildFeatures เปิด/ปิด ViewBinding, DataBinding, Compose aaptOptions กำหนดค่าการประมวลผลทรัพยากร: ignoreAssetsPattern, cruncherEnabled แต่ละองค์ประกอบของบล็อก android ปรับแต่งลักษณะเฉพาะของการบิวด์
android {
namespace = "com.example.myapp"
compileSdk = 35
buildToolsVersion = "35.0.0"
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 26
targetSdk = 35
versionCode = 5
versionName = "2.3.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("debug") { isDebuggable = true }
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
compose = true
}
}
dependencies ใน build.gradle คือไลบรารีและโมดูลที่เชื่อมต่อกับโปรเจกต์ บล็อก dependencies อยู่ในระดับเดียวกับบล็อก android Gradle รองรับหลายการกำหนดค่า: implementation (ไลบรารีพร้อมใช้งานในโมดูลนี้ ไม่ถ่ายทอด), api (ไลบรารีพร้อมใช้งานแบบถ่ายทอดไปยังโมดูลที่ขึ้นต่อกัน), compileOnly (เฉพาะการคอมไพล์, ไม่รวมใน APK), runtimeOnly (เฉพาะรันไทม์), annotationProcessor / ksp (ตัวประมวลผลคำอธิบายประกอบ), testImplementation (เฉพาะการทดสอบ), androidTestImplementation (เฉพาะการทดสอบเครื่องมือ)
ตั้งแต่ AGP 8.0 เป็นต้นไป คลาส R แบบไม่ถ่ายทอด — แต่ละไลบรารีมีคลาส R ของตัวเอง ซึ่งป้องกันข้อขัดแย้งของทรัพยากร ในบล็อก dependencies สิ่งสำคัญคือต้องใช้การกำหนดค่าที่ถูกต้อง: implementation ไม่เปิดเผย dependencies แบบถ่ายทอด ซึ่งเร่งการบิวด์ api เปิดเผย它们 — ใช้เมื่อไลบรารีส่งออกชนิดจากไลบรารีอื่น (เช่น Retrofit ใช้ชนิด OkHttp ใน API สาธารณะของมัน)
สำหรับการจัดการเวอร์ชัน แนะนำให้ใช้ BOM (Bill of Materials) — ไฟล์บิวด์ที่กำหนดเวอร์ชันไลบรารีที่เข้ากันได้ Firebase BOM: implementation(platform("com.google.firebase:firebase-bom:33.0.0")) หลังจากเชื่อมต่อ BOM คุณสามารถระบุเฉพาะชื่อไลบรารีโดยไม่ต้องระบุเวอร์ชัน — BOM จะเลือกเวอร์ชันที่เข้ากันได้โดยอัตโนมัติ ซึ่งช่วยขจัดข้อขัดแย้งระหว่าง dependencies แบบถ่ายทอดของไลบรารีต่างๆ BOM พร้อมใช้งานสำหรับ Firebase, Compose, Kotlin, Ktor, AndroidX
dependencies {
// BOM — การจัดการเวอร์ชัน
implementation(platform("androidx.compose:compose-bom:2024.12.01"))
implementation(platform("com.google.firebase:firebase-bom:33.0.0"))
// AndroidX และ Compose
implementation("androidx.core:core-ktx")
implementation("androidx.lifecycle:lifecycle-runtime-ktx")
implementation("androidx.activity:activity-compose")
implementation("androidx.compose.ui:ui")
// Network
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Firebase (เวอร์ชันจาก BOM)
implementation("com.google.firebase:firebase-firestore")
implementation("com.google.firebase:firebase-crashlytics")
// การทดสอบ
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
}
ในโปรเจกต์หลายโมดูล แต่ละโมดูลมี build.gradle ของตัวเอง ในการเชื่อมต่อโมดูลหนึ่งไปยังอีกโมดูลหนึ่ง ให้ใช้ไวยากรณ์ implementation(project(":module-name")) Gradle จะสร้างโมดูลใหม่โดยอัตโนมัติหากการกำหนดค่าเปลี่ยนแปลง สถาปัตยกรรมหลายโมดูลช่วยปรับปรุงเวลาบิวด์ (การบิวด์แบบเพิ่มหน่วย, ความขนาน) และแยกความรับผิดชอบระหว่างโมดูลคุณลักษณะ โมดูลหลัก และไลบรารี
ปัญหาสำคัญของโปรเจกต์หลายโมดูลคือ การทำซ้ำการกำหนดค่า หาก 10 โมดูลมี minSdk, compileSdk และ dependencies Compose เดียวกัน นั่นคือ 10 สำเนาใน build.gradle ต่างๆ วิธีแก้คือ Convention Plugins (เดิมคือ buildSrc) Convention Plugin คือปลั๊กอิน Gradle ที่เขียนด้วย Kotlin และนำไปใช้กับโมดูล: plugins { id("myapp.android.library") } ปลั๊กอินมีการกำหนดค่าร่วมกัน และการเปลี่ยนแปลงจะมีผลทันทีกับทุกโมดูล
ในการจัดระเบียบ Convention Plugins ให้ใช้ไดเรกทอรี build-logic/ ในรูทของโปรเจกต์ ประกอบด้วย includeBuild ใน settings.gradle และปลั๊กอิน Kotlin Convention Plugins สามารถเผยแพร่ไปยัง repository maven เพื่อนำกลับมาใช้ซ้ำระหว่างโปรเจกต์ Google แนะนำ Convention Plugins เป็นมาตรฐานสำหรับโปรเจกต์หลายโมดูล แทนที่ subprojects { } และ apply from การเปลี่ยนไปใช้ Convention Plugins ช่วยลด build.gradle ของโมดูลเหลือ 10-15 บรรทัด
// build-logic/src/main/kotlin/AndroidLibraryConventionPlugin.kt
class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(plugins) {
apply("com.android.library")
apply("org.jetbrains.kotlin.android")
}
extensions.configure<CommonExtension<*, *, *, *>> {
compileSdk = 35
defaultConfig { minSdk = 26 }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
}
}
}
// module/build.gradle.kts — หลัง Convention Plugin
plugins {
id("myapp.android.library")
}
dependencies {
implementation(project(":core:network"))
}
คำถามที่พบบ่อย
Kotlin DSL (.gradle.kts) คือคำแนะนำอย่างเป็นทางการของ Google การพิมพ์แบบคงที่ป้องกันข้อผิดพลาด IDE ให้การเติมข้อความอัตโนมัติ Groovy (.gradle) รองรับ แต่ฟีเจอร์ใหม่ของ Gradle และ AGP จะถูกทดสอบบน Kotlin DSL เป็นหลัก
namespace กำหนดแพ็กเกจสำหรับคลาสที่สร้างขึ้น (R.java, BuildConfig) ก่อนหน้านี้ namespace ถูกกำหนดใน AndroidManifest.xml ตั้งแต่ AGP 7+ เป็นต้นไป namespace จะระบุใน build.gradle เท่านั้น ค่าต้องตรงกับ applicationId (หรือต่างกันหากใช้ applicationIdSuffix)
เปิด Gradle Configuration Cache (org.gradle.configuration-cache=true), ใช้ Build Cache (org.gradle.caching=true), เปลี่ยนไปใช้ KSP แทน kapt, แบ่งโปรเจกต์หลายโมดูลและใช้ Convention Plugins และปิด product flavors ที่ไม่จำเป็น: ใน debug ให้บิวด์เพียง flavor เดียว
implementation: dependency มองเห็นได้เฉพาะภายในโมดูล โมดูลที่ขึ้นต่อกันไม่สามารถเข้าถึงคลาสแบบถ่ายทอด api: dependency ถูกเปิดเผยออกไปภายนอก ใช้ api เมื่อชนิดจาก dependency ถูกใช้ใน API สาธารณะของโมดูล (เช่น Retrofit ส่งออกชนิด OkHttp) implementation เร่งการบิวด์ — Gradle ไม่สร้างโมดูลที่ขึ้นต่อกันใหม่เมื่อ implementation dependency เปลี่ยนแปลง
build.gradle เป็นไฟล์เฉพาะของ Android สำหรับ iOS จะใช้ Xcode project (.xcodeproj) และ Swift Package Manager (Package.swift) อย่างไรก็ตาม มีเครื่องมือข้ามแพลตฟอร์ม (Kotlin Multiplatform, Flutter, React Native) ที่ใช้ build.gradle สำหรับบิวด์ส่วน Android ใน KMP build.gradle กำหนดค่า Android target
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม