ระบบบิลด์ Gradle ใน Android Studio ช่วยให้คุณรวมไฟล์ไบนารีภายนอกหรือโมดูลไลบรารีอื่นๆ ไว้ในบิลด์ของคุณเป็น Dependency ได้ ทรัพยากร Dependency อาจอยู่ในเครื่องหรือในที่เก็บระยะไกล และระบบจะรวมทรัพยากร Dependency แบบสับเปลี่ยนที่ประกาศไว้โดยอัตโนมัติด้วย หน้านี้จะอธิบายวิธีใช้ทรัพยากร Dependency กับโปรเจ็กต์ Android รวมถึงรายละเอียดเกี่ยวกับลักษณะการทำงานและการกำหนดค่าเฉพาะสำหรับปลั๊กอิน Android Gradle (AGP) หากต้องการดูคู่มือเชิงแนวคิดที่ละเอียดยิ่งขึ้นเกี่ยวกับการอ้างอิงของ Gradle คุณควรดูคำแนะนำ Gradle สำหรับการจัดการทรัพยากร Dependency ด้วย แต่โปรดทราบว่าโปรเจ็กต์ Android ของคุณต้องใช้เฉพาะการกำหนดค่าการขึ้นต่อกันที่กำหนดไว้ในหน้านี้เท่านั้น
เพิ่มไลบรารีหรือพึ่งพาของปลั๊กอิน
วิธีที่ดีที่สุดในการเพิ่มและจัดการทรัพยากร Dependency ของบิลด์คือการใช้แคตตาล็อกเวอร์ชัน ซึ่งเป็นวิธีที่โปรเจ็กต์ใหม่ใช้โดยค่าเริ่มต้น ส่วนนี้จะกล่าวถึงการกำหนดค่าประเภทต่างๆ ที่พบบ่อยที่สุดซึ่งใช้สำหรับโปรเจ็กต์ Android โปรดดูตัวเลือกเพิ่มเติมในเอกสารประกอบของ Gradle สำหรับตัวอย่างของแอปที่ใช้แคตตาล็อกเวอร์ชัน โปรดดู Now in Android หากคุณตั้งค่าทรัพยากร Dependency ของบิลด์ไว้แล้วโดยไม่มีแคตตาล็อกเวอร์ชัน และมีโปรเจ็กต์หลายโมดูล เราขอแนะนำให้ย้ายข้อมูล
ดูคำแนะนำในการเพิ่มและจัดการทรัพยากร Dependency แบบเนทีฟ (ที่พบไม่บ่อย) ได้ที่ทรัพยากร Dependency แบบเนทีฟ
ในตัวอย่างต่อไปนี้ เราเพิ่มทรัพยากร Dependency ของไฟล์ไบนารีระยะไกล (คลัง Macrobenchmark ของ Jetpack), ทรัพยากร Dependency ของโมดูลไลบรารีในเครื่อง (myLibrary
) และทรัพยากร Dependency ของปลั๊กอิน (ปลั๊กอิน Android Gradle) ลงในโปรเจ็กต์ ขั้นตอนทั่วไปในการเพิ่มทรัพยากร Dependency เหล่านี้ลงในโปรเจ็กต์มีดังนี้
เพิ่มชื่อแทนสำหรับเวอร์ชันทรัพยากร Dependency ที่คุณต้องการในส่วน
[versions]
ของไฟล์แคตตาล็อกเวอร์ชัน ซึ่งเรียกว่าlibs.versions.toml
(ในไดเรกทอรีgradle
ในมุมมองโปรเจ็กต์หรือสคริปต์ Gradle ในมุมมอง Android) ดังนี้[versions] agp = "8.3.0" androidx-macro-benchmark = "1.2.2" my-library = "1.4" [libraries] ... [plugins] ...
ชื่อแทนสามารถใส่ขีดกลางหรือขีดล่างได้ ชื่อแทนเหล่านี้จะสร้างค่าที่ซ้อนกัน ซึ่งคุณอ้างอิงได้ในสคริปต์บิลด์ การอ้างอิงจะขึ้นต้นด้วยชื่อแคตตาล็อก ซึ่งเป็นส่วน
libs
ของlibs.versions.toml
เมื่อใช้แคตตาล็อกเวอร์ชันเดียว เราขอแนะนำให้คงค่าเริ่มต้นของ "libs" ไว้เช่นเดิมเพิ่มชื่อแทนสำหรับทรัพยากร Dependency ในส่วน
[libraries]
(สำหรับไบนารีระยะไกลหรือโมดูลไลบรารีในเครื่อง) หรือ[plugins]
(สำหรับปลั๊กอิน) ของไฟล์libs.versions.toml
[versions] ... [libraries] androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidx-macro-benchmark" } my-library = { group = "com.myapplication", name = "mylibrary", version.ref = "my-library" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" }
ไลบรารีบางรายการมีอยู่ในข้อมูลรายการวัสดุ (BOM) ที่เผยแพร่ซึ่งจัดกลุ่มไลบรารีและเวอร์ชันของไลบรารี คุณสามารถใส่ BOM ไว้ในแคตตาล็อกเวอร์ชันและไฟล์บิลด์ แล้วปล่อยให้ระบบจัดการเวอร์ชันเหล่านั้นให้คุณ ดูรายละเอียดได้ที่หัวข้อการใช้ใบรายการวัสดุ
เพิ่มการอ้างอิงให้กับชื่อแทนทรัพยากร Dependency ไปยังสคริปต์บิลด์ของโมดูลที่ต้องการการอ้างอิง แปลงขีดล่างและขีดกลางของชื่อแทนเป็นจุด เมื่อคุณอ้างอิงจากสคริปต์บิลด์ สคริปต์การบิลด์ระดับโมดูลของเราจะมีลักษณะดังนี้
Kotlin
plugins { alias(libs.plugins.androidApplication) } dependencies { implementation(libs.androidx.benchmark.macro) implementation(libs.my.library) }
Groovy
plugins { alias 'libs.plugins.androidApplication' } dependencies { implementation libs.androidx.benchmark.macro implementation libs.my.library }
การอ้างอิงปลั๊กอินจะมี
plugins
ต่อจากชื่อแคตตาล็อก และการอ้างอิงเวอร์ชันจะมีversions
ต่อจากชื่อแคตตาล็อก (การอ้างอิงเวอร์ชันไม่ค่อยพบบ่อยนัก โปรดดูตัวอย่างการอ้างอิงเวอร์ชันใน Dependency ที่มีหมายเลขเวอร์ชันเดียวกัน) การอ้างอิงไลบรารีไม่มีตัวระบุlibraries
คุณจึงใช้versions
หรือplugins
ขึ้นต้นชื่อแทนไลบรารีไม่ได้
กำหนดค่าทรัพยากร Dependency
ภายในบล็อก dependencies
คุณจะประกาศทรัพยากร Dependency ของไลบรารีได้โดยใช้การกำหนดค่าการขึ้นต่อกันแบบต่างๆ (เช่น implementation
ที่แสดงก่อนหน้านี้) การกําหนดค่าการพึ่งพาแต่ละรายการจะให้คําแนะนําที่แตกต่างกันแก่ Gradle เกี่ยวกับวิธีใช้การพึ่งพา ตารางต่อไปนี้อธิบายการกำหนดค่าแต่ละรายการที่คุณใช้สำหรับทรัพยากร Dependency ในโปรเจ็กต์ Android ได้
การกำหนดค่า | ลักษณะการทำงาน |
---|---|
implementation |
Gradle เพิ่มทรัพยากร Dependency ไปยังคลาสพาธคอมไพล์และแพ็กเกจทรัพยากร Dependency ไปยังเอาต์พุตของบิลด์ เมื่อโมดูลกำหนดค่า implementation Dependency จะเป็นการแจ้งให้ Gradle ทราบว่าคุณไม่ต้องการให้โมดูลเปิดเผย Dependency ไปยังโมดูลอื่นๆ ในเวลาคอมไพล์ กล่าวคือ ทรัพยากร Dependency จะไม่พร้อมใช้งานกับโมดูลอื่นๆ ที่ขึ้นอยู่กับโมดูลปัจจุบัน
การใช้การกำหนดค่านี้แทน |
api |
Gradle เพิ่มทรัพยากร Dependency ไปยังคลาสพาธการคอมไพล์และสร้างเอาต์พุต เมื่อโมดูลมี api Dependency อยู่ แสดงว่าโมดูลดังกล่าวต้องการส่งออก Dependency นั้นไปยังโมดูลอื่นๆ แบบทรานซิทีฟ เพื่อให้โมดูลอื่นๆ ใช้งานได้ทั้งในช่วงรันไทม์และช่วงคอมไพล์
โปรดใช้การกำหนดค่านี้ด้วยความระมัดระวังและใช้สำหรับทรัพยากร Dependency ที่คุณต้องส่งออกไปยังผู้บริโภคต้นทางรายอื่นๆ ชั่วคราวเท่านั้น หากทรัพยากร Dependency ของ |
compileOnly |
Gradle จะเพิ่มการพึ่งพาลงในเส้นทางคอมไพล์เท่านั้น (กล่าวคือ จะไม่เพิ่มลงในเอาต์พุตการสร้าง) ซึ่งจะมีประโยชน์เมื่อคุณสร้างโมดูล Android และต้องใช้ทรัพยากรในระหว่างการคอมไพล์ แต่คุณเลือกที่จะแสดงทรัพยากรดังกล่าวที่รันไทม์หรือไม่ก็ได้ ตัวอย่างเช่น หากคุณใช้ไลบรารีที่มีเฉพาะคำอธิบายประกอบเวลาคอมไพล์ ซึ่งโดยทั่วไปจะใช้ในการสร้างโค้ดแต่มักไม่รวมอยู่ในเอาต์พุตของบิลด์ คุณอาจทำเครื่องหมายไลบรารีนั้น compileOnly
หากคุณใช้การกำหนดค่านี้ โมดูลไลบรารีของคุณต้องมีเงื่อนไขรันไทม์เพื่อตรวจสอบว่ามีการพึ่งพาหรือไม่ จากนั้นเปลี่ยนลักษณะการทํางานเพื่อให้ยังคงทํางานได้หากไม่ได้ระบุ การดำเนินการนี้ช่วยลดขนาดของแอปสุดท้ายด้วยการไม่เพิ่มทรัพยากร Dependency แบบชั่วคราวที่ไม่สำคัญ
หมายเหตุ: คุณใช้การกำหนดค่า |
runtimeOnly |
Gradle จะเพิ่มการพึ่งพาลงในเอาต์พุตการสร้างเท่านั้นเพื่อใช้ระหว่างรันไทม์ กล่าวคือ ไม่ได้เพิ่มลงใน classpath ของคอมไพล์
วิธีนี้ไม่ค่อยใช้ใน Android แต่มักใช้ในแอปพลิเคชันเซิร์ฟเวอร์เพื่อทำการบันทึก เช่น ไลบรารีอาจใช้ Logging API ที่ไม่มีการติดตั้งใช้งาน ผู้บริโภคของไลบรารีดังกล่าวจะเพิ่มไลบรารีนี้เป็นทรัพยากร Dependency ของ implementation และเพิ่มทรัพยากร Dependency ของ runtimeOnly เพื่อนําไปใช้การบันทึกจริงได้
|
ksp |
การกําหนดค่าเหล่านี้จะจัดหาไลบรารีที่ประมวลผลคําอธิบายประกอบและสัญลักษณ์อื่นๆ ในโค้ดก่อนที่จะคอมไพล์ โดยปกติแล้ว เครื่องมือเหล่านี้จะตรวจสอบโค้ดหรือสร้างโค้ดเพิ่มเติม ซึ่งจะช่วยลดโค้ดที่คุณจำเป็นต้องเขียน หากต้องการเพิ่มทรัพยากร Dependency ดังกล่าว คุณจะต้องเพิ่มการอ้างอิงไปยังคลาสพาธของตัวประมวลผลคำอธิบายประกอบโดยใช้การกำหนดค่า หากไฟล์ JAR มีไฟล์ต่อไปนี้ ปลั๊กอิน Android Gradle จะถือว่าทรัพยากร Dependency เป็นตัวประมวลผลคำอธิบายประกอบ
หากปลั๊กอินตรวจพบตัวประมวลผลคำอธิบายประกอบที่อยู่ในคลาสพาธการคอมไพล์ ปลั๊กอินจะสร้างข้อผิดพลาดของบิลด์
เมื่อตัดสินใจว่าจะใช้การกําหนดค่าใด ให้พิจารณาสิ่งต่อไปนี้
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้โปรแกรมประมวลผลคำอธิบายประกอบได้ที่เพิ่มโปรแกรมประมวลผลคำอธิบายประกอบ |
lintChecks |
ใช้การกําหนดค่านี้เพื่อรวมไลบรารีที่มีการตรวจสอบ Lint ที่คุณต้องการให้ Gradle เรียกใช้เมื่อสร้างโปรเจ็กต์แอป Android โปรดทราบว่า AAR ที่มีไฟล์ |
lintPublish |
ใช้การกำหนดค่านี้ในโปรเจ็กต์คลัง Android เพื่อรวมการตรวจสอบ Lint ที่ต้องการให้ Gradle คอมไพล์เป็นไฟล์ lint.jar และแพ็กเกจใน AAR การดำเนินการนี้จะทำให้โปรเจ็กต์ที่ใช้ AAR นำการตรวจสอบ Lint เหล่านั้นไปใช้ด้วย หากก่อนหน้านี้คุณใช้การกำหนดค่า lintChecks เพื่อรวมการตรวจสอบ Lint ไว้ใน AAR ที่เผยแพร่ คุณต้องย้ายข้อมูลการพึ่งพาเหล่านั้นเพื่อใช้การกำหนดค่า lintPublish แทน
Kotlindependencies { // Executes lint checks from the ":checks" project at build time. lintChecks(project(":checks")) // Compiles lint checks from the ":checks-to-publish" into a // lint.jar file and publishes it to your Android library. lintPublish(project(":checks-to-publish")) } Groovydependencies { // Executes lint checks from the ':checks' project at build time. lintChecks project(':checks') // Compiles lint checks from the ':checks-to-publish' into a // lint.jar file and publishes it to your Android library. lintPublish project(':checks-to-publish') } |
กำหนดค่าการพึ่งพาสำหรับตัวแปรของบิวด์ที่เฉพาะเจาะจง
การกำหนดค่าก่อนหน้านี้ทั้งหมดจะใช้ทรัพยากร Dependency กับตัวแปรบิลด์ทั้งหมด หากคุณต้องการประกาศทรัพยากร Dependency สำหรับชุดแหล่งที่มาของตัวแปรบิลด์เฉพาะชุดใดชุดหนึ่งเท่านั้นหรือสำหรับชุดต้นทางการทดสอบ ให้ใช้อักษรตัวพิมพ์ใหญ่สำหรับชื่อการกำหนดค่าและนำหน้าด้วยชื่อชุดตัวแปรบิลด์หรือชุดแหล่งที่มาของการทดสอบ
เช่น หากต้องการเพิ่มทรัพยากร Dependency ของไบนารีระยะไกลเฉพาะกับเวอร์ชันผลิตภัณฑ์ "ฟรี" โดยใช้การกำหนดค่า implementation
ให้ใช้
Kotlin
dependencies { freeImplementation("com.google.firebase:firebase-ads:21.5.1") }
ดึงดูด
dependencies { freeImplementation 'com.google.firebase:firebase-ads:21.5.1' }
อย่างไรก็ตาม หากต้องการเพิ่มทรัพยากร Dependency สำหรับผลิตภัณฑ์ย่อยที่รวมเวอร์ชันผลิตภัณฑ์และประเภทบิลด์ คุณต้องเริ่มต้นชื่อการกำหนดค่าดังนี้
Kotlin
// Initializes a placeholder for the freeDebugImplementation dependency configuration. val freeDebugImplementation by configurations.creating dependencies { freeDebugImplementation(project(":free-support")) }
Groovy
configurations { // Initializes a placeholder for the freeDebugImplementation dependency configuration. freeDebugImplementation {} } dependencies { freeDebugImplementation project(":free-support") }
วิธีเพิ่ม implementation
Dependencies สําหรับการทดสอบในเครื่องและการทดสอบที่มีเครื่องมือวัดจะมีลักษณะดังนี้
Kotlin
dependencies { // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") }
Groovy
dependencies { // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' }
อย่างไรก็ตาม การกำหนดค่าบางอย่างอาจไม่สมเหตุสมผลในกรณีนี้ ตัวอย่างเช่น เนื่องจากโมดูลอื่นๆ ไม่สามารถพึ่งพา androidTest
คุณจึงได้รับคำเตือนต่อไปนี้หากใช้การกำหนดค่า androidTestApi
WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with 'androidTestImplementation'.
ลําดับการขึ้นต่อกัน
ลำดับที่คุณแสดงรายการทรัพยากร จะเป็นตัวบ่งชี้ลำดับความสำคัญของแต่ละรายการ โดยคลังแรกจะมีลำดับความสำคัญสูงกว่าคลังที่สอง คลังที่สองจะมีลำดับความสำคัญสูงกว่าคลังที่สาม และต่อไปเรื่อยๆ ลําดับนี้สําคัญในกรณีที่ผสานทรัพยากรหรือผสานองค์ประกอบไฟล์ Manifest ลงในแอปจากไลบรารี
เช่น หากโปรเจ็กต์ประกาศสิ่งต่อไปนี้
- การพึ่งพา
LIB_A
และLIB_B
(ตามลำดับ) - และ
LIB_A
ขึ้นอยู่กับLIB_C
และLIB_D
(ตามลำดับ) - และ
LIB_B
ยังขึ้นอยู่กับLIB_C
ด้วย
จากนั้นลําดับความเกี่ยวข้องแบบคงที่จะเป็นดังนี้
LIB_A
LIB_D
LIB_B
LIB_C
วิธีนี้ช่วยรับประกันว่าทั้ง LIB_A
และ LIB_B
จะลบล้าง LIB_C
ได้ และ LIB_D
ยังคงมีลำดับความสำคัญสูงกว่า LIB_B
เนื่องจาก LIB_A
(ขึ้นอยู่กับค่านี้) มีลำดับความสำคัญสูงกว่า LIB_B
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีผสานไฟล์ Manifest จากแหล่งที่มา/ข้อกําหนดของโปรเจ็กต์ต่างๆ ได้ที่ผสานไฟล์ Manifest หลายไฟล์
ข้อมูลเกี่ยวกับทรัพยากรที่จำเป็นสำหรับ Play Console
เมื่อสร้างแอป AGP จะรวมข้อมูลเมตาที่อธิบายทรัพยากร Dependency ของไลบรารีที่คอมไพล์ไว้ในแอปของคุณ เมื่ออัปโหลดแอป Play Console จะตรวจสอบข้อมูลเมตานี้เพื่อแจ้งเตือนปัญหาที่ทราบเกี่ยวกับ SDK และทรัพยากร Dependency ที่แอปของคุณใช้ และในบางกรณีจะให้ความคิดเห็นที่นําไปใช้แก้ปัญหาได้
ระบบจะบีบอัด เข้ารหัสด้วยคีย์การรับรองของ Google Play และจัดเก็บไว้ในบล็อกการรับรองของแอปรุ่น เราขอแนะนำให้เก็บไฟล์นี้ไว้เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีและปลอดภัย คุณเลือกไม่ใช้ได้โดยการรวมบล็อก dependenciesInfo
ต่อไปนี้ในไฟล์ build.gradle.kts
ของโมดูล
android {
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับนโยบายและปัญหาที่อาจเกิดขึ้นกับ Dependency ได้ที่หน้าการสนับสนุนของเราเกี่ยวกับการใช้ SDK ของบุคคลที่สามในแอป
ข้อมูลเชิงลึกของ SDK
Android Studio จะแสดงคำเตือน Lint ในไฟล์แคตตาล็อกเวอร์ชันและกล่องโต้ตอบโครงสร้างโปรเจ็กต์สำหรับ SDK สาธารณะในดัชนี SDK ของ Google Play เมื่อมีปัญหาต่อไปนี้
- ผู้เขียนได้ทําเครื่องหมาย SDK ว่าล้าสมัย
- SDK ละเมิดนโยบายของ Play
คำเตือนเป็นสัญญาณว่าคุณควรอัปเดตไลบรารีเหล่านั้น เนื่องจากการใช้เวอร์ชันที่ล้าสมัยอาจทำให้คุณเผยแพร่ไปยัง Google Play Console ไม่ได้ในอนาคต
เพิ่มการพึ่งพาบิลด์โดยไม่ใช้แคตตาล็อกเวอร์ชัน
เราขอแนะนำให้ใช้แคตตาล็อกเวอร์ชันเพื่อเพิ่มและจัดการทรัพยากร Dependency แต่โปรเจ็กต์พื้นฐานอาจไม่จำเป็นต้องใช้ ต่อไปนี้คือตัวอย่างของไฟล์บิลด์ที่ไม่ได้ใช้แคตตาล็อกเวอร์ชัน
Kotlin
plugins { id("com.android.application") } android { ... } dependencies { // Dependency on a remote binary implementation("com.example.android:app-magic:12.3") // Dependency on a local library module implementation(project(":mylibrary")) }
ดึงดูด
plugins { id 'com.android.application' } android { ... } dependencies { // Dependency on a remote binary implementation 'com.example.android:app-magic:12.3' // Dependency on a local library module implementation project(':mylibrary') }
ไฟล์บิลด์นี้ประกาศการพึ่งพาไลบรารี "app-magic" เวอร์ชัน 12.3 ภายในกลุ่มเนมสเปซ "com.example.android" การประกาศการขึ้นต่อกันของไบนารีระยะไกลเป็นชื่อย่อสำหรับรายการต่อไปนี้
Kotlin
implementation(group = "com.example.android", name = "app-magic", version = "12.3")
ดึงดูด
implementation group: 'com.example.android', name: 'app-magic', version: '12.3'
ไฟล์บิลด์จะประกาศทรัพยากร Dependency ในโมดูลไลบรารี Android ที่ชื่อ "mylibrary" ด้วย ชื่อนี้ต้องตรงกับชื่อไลบรารีที่กำหนดไว้ด้วย include:
ในไฟล์ settings.gradle.kts
ของคุณ เมื่อคุณสร้างแอป ระบบบิลด์จะรวบรวมโมดูลไลบรารีและจัดแพ็กเกจเนื้อหาที่ได้รวบรวมไว้ในแอป
ไฟล์บิลด์จะประกาศการพึ่งพาปลั๊กอิน Gradle ของ Android (com.application.android
) ด้วย หากมีโมดูลหลายรายการที่ใช้ปลั๊กอินเดียวกัน คุณจะมีปลั๊กอินได้เพียงเวอร์ชันเดียวใน classpath ของบิลด์ในโมดูลทั้งหมด แทนที่จะระบุเวอร์ชันในสคริปต์บิลด์ของโมดูลแต่ละรายการ คุณควรใส่ทรัพยากร Dependency ของปลั๊กอินไว้ในสคริปต์บิลด์รูทพร้อมกับเวอร์ชัน รวมทั้งระบุว่าจะไม่ใช้ การเพิ่ม apply false
จะบอกให้ Gradle จดบันทึกเวอร์ชันของปลั๊กอิน แต่ไม่ให้นำไปใช้ในบิลด์รูท
โดยปกติแล้วสคริปต์บิลด์รูทจะว่างเปล่ายกเว้นบล็อก plugins
นี้
Kotlin
plugins { id("org.jetbrains.kotlin.android") version "1.9.0" apply false }
ดึงดูด
plugins { id ‘com.android.application’ version ‘8.3.0-rc02’ apply false }
หากมีโปรเจ็กต์โมดูลเดียว คุณสามารถระบุเวอร์ชันอย่างชัดเจนในสคริปต์บิลด์ระดับโมดูลและปล่อยสคริปต์บิลด์ระดับโปรเจ็กต์ว่างไว้ได้ ดังนี้
Kotlin
plugins { id("com.android.application") version "8.3.0" }
ดึงดูด
plugins { id 'com.android.application' version '8.3.0-rc02' }