การพึ่งพากันระหว่างเครื่องมือและไลบรารี

Dependency ของบิลด์คือคอมโพเนนต์ภายนอกที่จำเป็นต่อการสร้างโปรเจ็กต์ให้สำเร็จ บิลด์อาจใช้ไลบรารี ปลั๊กอิน โปรเจ็กต์ย่อย, Android SDK, เครื่องมือต่างๆ เช่น คอมไพเลอร์ Kotlin และ Java, สภาพแวดล้อมการพัฒนา เช่น Android Studio และ Gradle เอง

แต่ละรายการที่ต้องใช้อาจต้องใช้รายการอื่นๆ เพิ่มเติม เราเรียกสิ่งเหล่านี้ว่าการพึ่งพาแบบสื่อกลาง และอาจเพิ่มการพึ่งพาโดยรวมที่แอปพลิเคชันของคุณใช้อย่างรวดเร็ว เมื่อต้องการอัปเกรด Dependency ไม่ว่าจะเป็นไลบรารี เครื่องมือ หรือ Android SDK การอัปเกรดดังกล่าวอาจส่งผลแบบเป็นขั้นเป็นตอน ซึ่งจะอัปเกรด Dependency อื่นๆ อีกมากมาย

โดยทั่วไปแล้ว ปัญหานี้จะไม่เกิดขึ้นเนื่องจากไลบรารีจำนวนมากใช้รูปแบบที่เรียกว่าการติดแท็กเวอร์ชันแบบเป็นความหมาย ไลบรารีเหล่านี้จะจํากัดประเภทการเปลี่ยนแปลงที่ทําเพื่อให้เข้ากันได้กับเวอร์ชันที่ต่ำกว่า

การกำหนดเวอร์ชันทางอรรถศาสตร์เป็นไปตามรูปแบบ major.minor.patch เช่น ในหมายเลขเวอร์ชัน 4.8.3 ตัวเลข 4 คือเวอร์ชัน major, 8 คือเวอร์ชัน minor และ 3 คือหมายเลข patch เมื่อส่วน major มีการเปลี่ยนแปลง ไลบรารีอาจมีการเปลี่ยนแปลงที่ส่งผลอย่างมากใน API หรือลักษณะการทํางาน ซึ่งอาจส่งผลต่อลักษณะการทํางานของบิลด์หรือแอปพลิเคชัน

เมื่อส่วน minor (ฟีเจอร์ใหม่) หรือ patch (การแก้ไขข้อบกพร่อง) มีการเปลี่ยนแปลง นักพัฒนาไลบรารีจะแจ้งให้คุณทราบว่าไลบรารียังคงใช้งานร่วมกันได้และไม่ควรส่งผลกระทบต่อแอปพลิเคชันของคุณ

ความสัมพันธ์ในบิลด์

บิลด์ Android มีความสัมพันธ์ระหว่างสิ่งต่อไปนี้

  • ซอร์สโค้ด - โค้ดและทรัพยากรที่คุณควบคุมได้
  • ไลบรารี Dependency - ไลบรารีหรือโมดูลภายนอกที่โปรเจ็กต์และโปรเจ็กต์ย่อยรวมไว้เมื่อสร้าง
  • เครื่องมือ - คอมไพเลอร์ ปลั๊กอิน และ SDK ที่แปลแหล่งที่มาของคุณเป็นแอปพลิเคชันหรือไลบรารี
ความสัมพันธ์และการพึ่งพาของบิลด์
รูปที่ 1 สร้างความสัมพันธ์

ซอร์สโค้ด

ซอร์สโค้ดคือโค้ด Kotlin หรือ Java ที่คุณเขียนในแอปพลิเคชันหรือไลบรารี (ดูรายละเอียดเกี่ยวกับการใช้ C++ ได้ที่ Android NDK)

ซอร์สโค้ดใช้ไลบรารี (รวมถึงไลบรารีรันไทม์ Kotlin และ Java) และ Android SDK และต้องคอมไพล์ด้วยคอมไพเลอร์ Kotlin หรือ Java ที่เกี่ยวข้อง

โค้ดต้นฉบับบางรายการมีคำอธิบายประกอบที่ต้องประมวลผลเพิ่มเติม เช่น หากคุณเขียนโค้ด Jetpack Compose ให้เพิ่มคำอธิบายประกอบ เช่น @Composable ที่ต้องประมวลผลโดยปลั๊กอินคอมไพเลอร์ Compose Kotlin เครื่องมือประมวลผลสัญลักษณ์ Kotlin (KSP) หรือเครื่องมือประมวลผลคำอธิบายประกอบแยกต่างหากอาจประมวลผลคำอธิบายประกอบอื่นๆ

Dependency ของไลบรารี

ไลบรารีประกอบด้วยไบต์โค้ดที่ดึงมาเป็นส่วนหนึ่งของแอปพลิเคชัน ซึ่งอาจเป็น JAR ของ Java, ไลบรารี Android (AAR) หรือโปรเจ็กต์ย่อยในบิลด์ ไลบรารีจํานวนมากใช้การกําหนดเวอร์ชันแบบเชิงความหมาย ซึ่งจะช่วยให้คุณเข้าใจว่าไลบรารียังคงเข้ากันได้ (หรือไม่) เมื่ออัปเกรด

ไลบรารีอาจขึ้นอยู่กับไลบรารีอื่นๆ เพื่อใช้ซ้ำ ซึ่งเรียกว่าDependency แบบทรานซิทีฟ วิธีนี้ช่วยลด Dependency ที่คุณต้องจัดการอย่างชัดเจน โดยคุณระบุ Dependency ที่ใช้โดยตรง และ Gradle จะดึง Dependency เหล่านั้นพร้อมกับ Dependency แบบสื่อกลางเหล่านั้น โปรดทราบว่าเมื่อคุณอัปเกรดการพึ่งพาโดยตรง แพ็กเกจเหล่านั้นอาจอัปเกรดการพึ่งพาแบบเปลี่ยนผ่านด้วย

บางครั้งไลบรารีอาจกำหนดเวอร์ชันขั้นต่ำของ Android SDK ที่รันไทม์ (minSdk) หรือเวลาคอมไพล์ (compileSdk) ซึ่งจำเป็นเมื่อไลบรารีใช้ฟังก์ชันที่รวมอยู่ใน Android SDK หรือ JDK API ที่ให้มา minSdk ที่มีประสิทธิภาพของแอปพลิเคชันคือ minSdk ที่สูงที่สุดที่แอปพลิเคชันของคุณและไลบรารี Dependency ทั้งหมดทั้งแบบโดยตรงและแบบสื่อกลางขอ

การใช้ไลบรารีบางรายการอาจต้องใช้ปลั๊กอิน Gradle ที่เฉพาะเจาะจง ปลั๊กอินตัวช่วยเหล่านี้มักจะติดตั้งตัวประมวลผลสัญลักษณ์ Kotlin หรือตัวประมวลผลคำอธิบายประกอบอื่นๆ ซึ่งสร้างโค้ดหรือแก้ไขการคอมไพล์แหล่งที่มาเพื่อรองรับการใช้ฟีเจอร์ของไลบรารี เช่น Jetpack Room มีคำอธิบายประกอบและ KSP ที่เปลี่ยนคำอธิบายประกอบและ KSP เหล่านั้นให้เป็นโค้ดที่สร้างขึ้นเพื่อดึงข้อมูลและแก้ไขข้อมูลในฐานข้อมูล Jetpack Compose กำหนดให้ต้องใช้ปลั๊กอินคอมไพเลอร์ Compose เพื่อแก้ไขฟังก์ชันที่มีคำอธิบายประกอบเพื่อจัดการวิธีและเวลาเรียกใช้ฟังก์ชันนั้นอีกครั้ง

เครื่องมือ

Gradle

Gradle เป็นเครื่องมือสร้างที่อ่านไฟล์บิลด์และสร้างแอปพลิเคชันหรือไลบรารี รวมถึงแสดง API สำหรับปลั๊กอินเพื่อขยายความสามารถ Gradle เรียกใช้หลายกระบวนการบนเครื่องเสมือน Java อย่างน้อย 1 เครื่อง และปลั๊กอิน Java จะเรียกใช้เครื่องมือ Java ภายใน JDK

ปลั๊กอิน Gradle

ปลั๊กอิน Gradle จะขยาย Gradle โดยการกําหนดงานและการกําหนดค่าใหม่ การใช้ปลั๊กอินกับบิลด์จะเปิดใช้ความสามารถบางอย่างของบิลด์ที่กำหนดค่าเป็นข้อมูลในสคริปต์บิลด์ สําหรับบิลด์ Android ปลั๊กอิน Gradle ที่สําคัญที่สุดคือ ปลั๊กอิน Android Gradle (AGP)

คอมไพเลอร์

คอมไพเลอร์ Kotlin หรือ Java จะเปลี่ยนซอร์สโค้ดของคุณให้เป็นไบต์โค้ดที่เรียกใช้ได้ คอมไพเลอร์ Kotlin จะแสดง API ของปลั๊กอินที่ช่วยให้การวิเคราะห์ภายนอกและการสร้างโค้ดทำงานภายในคอมไพเลอร์ได้โดยตรง ซึ่งจะเข้าถึงโครงสร้างโค้ดที่แยกวิเคราะห์

ปลั๊กอินคอมไพเลอร์

ปลั๊กอินคอมไพเลอร์จะดำเนินการวิเคราะห์และสร้างโค้ดภายในคอมไพเลอร์ Kotlin ขณะที่คอมไพเลอร์ Kotlin กำลังวิเคราะห์โค้ดของคุณ และระบบจะติดตั้งปลั๊กอินเมื่อคุณใช้ปลั๊กอิน Gradle กับบิลด์

Android SDK

Android SDK มีแพลตฟอร์ม Android และ Java API สําหรับ Android เวอร์ชันหนึ่งๆ รวมถึงเครื่องมือที่เกี่ยวข้อง เครื่องมือเหล่านี้จะช่วยคุณจัดการ SDK, สร้างแอปพลิเคชัน รวมถึงสื่อสารและจําลองอุปกรณ์ Android

Android SDK แต่ละเวอร์ชันมี Java API ที่เฉพาะเจาะจงซึ่งซอร์สโค้ดของคุณเข้าถึงได้ รวมถึงรองรับการถอด Sugar เพื่อใช้ API เหล่านั้นใน Android เวอร์ชันเก่า

JDK

Java Development Kit ซึ่งมีไลบรารีและไฟล์ปฏิบัติการ Java เพื่อคอมไพล์ซอร์สโค้ด Java และเรียกใช้แอปพลิเคชัน Java บิลด์ Android จะใช้ JDK หลายรายการ ดูรายละเอียดเพิ่มเติมได้ที่เวอร์ชัน Java ในบิลด์ Android

ขอบเขต Gradle

Gradle จะจัดกลุ่มทรัพยากร Dependency ของไลบรารีไว้ในขอบเขตต่างๆ (เรียกว่าการกำหนดค่าใน Gradle API) ซึ่งช่วยให้คุณระบุชุดทรัพยากร Dependency ของไลบรารีต่างๆ เพื่อใช้ในส่วนต่างๆ ของการสร้างได้ ตัวอย่างเช่น คุณอาจไม่ต้องการรวมไลบรารีทดสอบ เช่น JUnit ไว้ในแอปพลิเคชันหรือไลบรารีที่เผยแพร่ แต่ต้องการใช้เมื่อสร้างและเรียกใช้การทดสอบหน่วย นอกจากนี้ คุณยังใช้ขอบเขตเพื่อเพิ่มตัวประมวลผลสัญลักษณ์หรือการกำกับเนื้อหาเพื่อวิเคราะห์โค้ดได้ด้วย

ตัวอย่างเช่น AGP จะกําหนดขอบเขต implementation และ api ซึ่งเป็นวิธีระบุว่าจะแสดงข้อมูลการพึ่งพาต่อผู้ใช้โปรเจ็กต์ย่อยหรือไม่ ดูคำอธิบายของขอบเขตเหล่านี้และขอบเขตอื่นๆ ที่ใช้ในบิลด์ Android ได้ที่หัวข้อกำหนดค่า Dependency

เพิ่มการพึ่งพาไลบรารีในบล็อก dependencies ของไฟล์บิลด์ โดยใช้สตริง group:artifact:version ดังนี้

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

Groovy

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

หรือในแคตตาล็อกเวอร์ชัน

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

และระบุตัวแปรที่สร้างขึ้นในไฟล์บิลด์

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

Groovy

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}