สร้าง Gradle Plugin ด้วย Kotlin เพื่อใช้งานบน Android - Getting Started
หลังจากเข้าใจโครงสร้างของ Android Gradle Plugin เบื้องต้นแล้ว สิ่งที่ต้องทำก่อนที่จะเขียน Gradle Plugin หรือ Convention Plugin ก็คือการเตรียมโปรเจคให้พร้อมเสียก่อน
เพื่อความเข้าใจง่าย เจ้าของบล็อกจะขอเรียกว่า Gradle Plugin แทน Convention Plugin
บทความในชุดเดียวกัน
- Introduction
- Android Gradle Plugin
- Getting Started [Now Reading]
- [ตัวอย่าง] สร้าง Dependency Sharing Plugin เพื่อใช้กับทุก Module
- [ตัวอย่าง] สร้าง Firebase Plugin เพื่อแยกคำสั่งของ Firebase ออกจาก App Module
- [ตัวอย่าง] สร้าง Configuration Sharing Plugin เพื่อใช้งานใน Library Module
สำหรับการทำตามขั้นตอนต่าง ๆ ในบทความนี้ แนะนำให้สร้างโปรเจคขึ้นมาใหม่เพื่อทำตามและทำความเข้าใจเสียก่อน แล้วค่อยลองทำกับในโปรเจคแอนดรอยด์ที่ต้องการในภายหลัง
เมื่อพร้อมแล้ว ก็เริ่มกันได้เลย
เพิ่ม buildSrc
เข้าไปในโปรเจค
อย่างที่บอกไปในบทความแรกสุดของบทความชุดนี้ เจ้าของบล็อกจะสร้าง Gradle Plugin ไว้ใน buildSrc
ของโปรเจคแอนดรอยด์ เพราะต้องการใช้แค่ภายในโปรเจคเท่านั้น
buildSrc
เป็น Precompiled Script ที่จะทำงานก่อนที่ Gradle จะ Build Project ทำให้เราสามารถเตรียมคำสั่งให้กับ Build Script ที่ต้องการใช้งานในโปรเจคได้
โดยให้สร้าง buildSrc
พร้อมกับ build.gradle.kts
ไว้ข้างในนั้น เพื่อย้ายคำสั่งบางส่วนใน settings.gradle.kts
และ build.gradle.kts
ของโปรเจคไปไว้ในนั้นแทน
ย้ายคำสั่งบางส่วนใน settings.gradle.kts
และ build.gradle.kts
เข้าไปไว้ใน buildSrc
สมมติว่าใน settings.gradle.kts
และ build.gradle.kts
ของโปรเจคมีคำสั่งเกี่ยวกับ Gradle Plugin เป็นแบบนี้
// settings.gradle.kts (Project)
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
/* ... */
// build.gradle.kts (Project)
plugins {
id("com.android.application") version "8.1.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
}
buildscript {
dependencies {
classpath("com.google.gms:google-services:4.4.0")
}
}
/* ... */
ให้ย้าย pluginManagement {..}
ใน settings.gradle.kts
ไปไว้ใน buildSrc/build.gradle.kts
แบบนี้แทน
// build.gradle.kts (buildSrc)
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins {
`kotlin-dsl`
}
ในbuild.gradle.kts
ของbuildSrc
จำเป็นต้องเพิ่มkotlin-dsl
ไว้ในplugins {..}
ด้วยเสมอ
ส่วน Gradle Plugin ที่ประกาศไว้ใน build.gradle.kts
ของโปรเจคให้ย้ายมาประกาศไว้ในนี้ด้วยเช่นกัน
// build.gradle.kts (buildSrc)
/* ... */
dependencies {
implementation("com.android.tools.build:gradle:8.1.2")
implementation("org.jetbrains.kotlin.android:org.jetbrains.kotlin.android.gradle.plugin:1.9.10")
implementation("com.google.gms:google-services:4.4.0")
}
จุดสังเกตสำหรับ Gradle Plugin จากโค้ดตัวอย่างข้างบน ก็คือเราจะต้องแปลง ID ให้เป็น Classpath แล้วเปลี่ยนคำสั่ง classpath
ให้เป็น implementation
แทน ยกตัวอย่างเช่น
ID | Classpath |
---|---|
com.android.application |
com.android.tools.build:gradle |
com.android.library |
com.android.tools.build:gradle |
org.jetbrains.kotlin.android |
org.jetbrains.kotlin.android:org.jetbrains.kotlin.android.gradle.plugin |
com.google.gms.google-services |
com.google.gms:google-services |
com.google.firebase.crashlytics |
com.google.firebase:firebase-crashlytics |
com.google.firebase.firebase-perf |
com.google.firebase:firebase-perf |
ถ้าไม่รู้ว่า Grald Plugin นั้น ๆ มี Classpath เป็นอะไร ให้ลองเช็คใน
- Gradle Plugin ของ Google หรือ Firebase – MVN Repository
- 3rd Party Gradle Plugin – Gradle Plugin Search
โดยทั้ง 2 เว็ปนี้จะเป็นเว็ปที่รวบรวมข้อมูลของ Gradle Plugin และมีรายละเอียดต่าง ๆ เกี่ยวกับ Plugin ตัวนั้น ๆ รวมไปถึง Classpath ด้วย
สรุปโค้ดทั้งหมดในตอนนี้
// build.gradle.kts (buildSrc)
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins {
`kotlin-dsl`
}
dependencies {
implementation("com.android.tools.build:gradle:8.1.2")
implementation("org.jetbrains.kotlin.android:org.jetbrains.kotlin.android.gradle.plugin:1.9.10")
implementation("com.google.gms:google-services:4.4.0")
}
// build.gradle.kts (Project)
// ย้ายไปไว้ใน buildSrc หมดแล้ว
// settings.gradle.kts (Project)
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
/* ... */
เมื่อมาถึงขั้นตอนนี้แล้ว ควรจะกด Run App แล้วสามารถ Build Project ได้ปกติ ถ้ามีปัญหาใด ๆ ระหว่างนี้ให้ลองตรวจสอบโค้ดใหม่ทั้งหมดอีกครั้งก่อนที่จะไปขั้นตอนต่อไป
สร้าง Gradle Plugin หรือ Convention Plugin
นักพัฒนาสามารถเพิ่มโค้ดใน buildSrc
ได้เหมือนกับการเขียนโค้ดปกติเลย เพียงแต่โค้ดที่อยู่ในนั้นจะเป็นโค้ดสำหรับ Gradle
ดังนั้นการสร้าง Plugin จึงสามารถสร้างไฟล์ไว้ในนั้นได้เลย ยกตัวอย่างเช่น เจ้าของบล็อกสร้างไฟล์สำหรับ Plugin เพิ่มเข้าไปแบบนี้
และเตรียมโค้ดไว้ข้างในแบบนี้
package com.akexorcist.sleepingforless.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project
class DependencySharingConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
println("Hello from DependencySharingConventionPlugin")
// Implement your custom Gradle plugin here
}
}
โค้ดตัวอย่างนี้จะเป็นโค้ดเริ่มต้นสำหรับการสร้าง Gradle Plugin ใด ๆ ก็ตาม ซึ่งในตอนนี้จะยังไม่ได้ทำอะไรนอกไปจากแสดงข้อความผ่าน Log ด้วยคำสั่ง println
และนอกจากจะเตรียมโค้ดสำหรับ Gradle Plugin แล้ว จะต้องเพิ่มคำสั่งใน build.gradle.kts
ของ buildSrc
ด้วยเสมอ เพื่อกำหนด Plugin ID และ Classpath เพื่อให้นำไปใช้ในโปรเจคได้
จากตัวอย่างโค้ดก่อนหน้าจะต้องกำหนดค่าใน build.gradle.kts
ของ buildSrc
แบบนี้
// build.gradle.kts (buildSrc)
/* ... */
gradlePlugin {
plugins {
register("dependencySharingConventionPlugin") {
id = "akexorcist.dependency-sharing.convention"
implementationClass = "com.akexorcist.sleepingforless.gradle.DependencySharingConventionPlugin"
}
}
}
ให้ทำการ Sync Gradle ใหม่ เพียงเท่านี้ Gradle Plugin ตัวนี้ก็จะพร้อมนำไปใช้งานในโปรเจคแล้ว (ถ้าโค้ดถูกต้องนะ)
ให้ทดสอบการทำงานของ Gradle Plugin ด้วยการเพิ่มเข้าไปใน App Module แบบนี้
// build.gradle.kts (App Module)
plugins {
/* ... */
id("akexorcist.dependency-sharing.convention")
}
/* ... */
จากนั้นให้ Sync Gradle แล้วเปิด Log ในหน้าต่าง Build ดู ก็จะพบว่ามีข้อความจากคำสั่ง println
แสดงขึ้นมาใน Log ด้วย
นั่นหมายความว่า Gradle Plugin ที่เราสร้างขึ้นมาเองพร้อมใช้งานแล้วนั่นเอง
สรุป
ขั้นตอนทั้งหมดในบทความนี้จะเป็นเพียงการสร้าง Gradle Plugin เปล่า ๆ ขึ้นมาโดยยังไม่ได้เพิ่มคำสั่งใด ๆ เข้าไป สำหรับการใช้คำสั่งต่าง ๆ เพื่อให้ Gradle Plugin ทำอะไรบางอย่างกับโปรเจคแอนดรอยด์จะขอพูดในบทความถัดไปแทน โดยจะแบ่งออกหลายบทความเพื่อยกตัวอย่างการนำไปประยุกต์ใช้งานในแต่ละแบบ เพื่อช่วยให้ผู้ที่หลงเข้ามาอ่านเข้าใจวิธีการใช้งาน Gradle Plugin หรือ Convention Plugin มากขึ้น