แชร์เรื่องนี้
Hilt –โซลูชัน DI สำหรับ Android Developer ที่ Jetpack แนะนำให้ใช้
โดย Seven Peaks เมื่อ 26 เม.ย. 2022, 17:16:00
แนะนำวิธีการใช้งานอย่างละเอียดสำหรับการพัฒนาแอปพลิเคชันบน Android ในปี 2022
วิธีนำ Hilt library มาใช้ในการพัฒนาบน Android
ใน session สำหรับแบ่งปันความรู้ของทีมงานที่ Seven Peaks Software บรรดาผู้เชี่ยวชาญด้าน Android ของเราได้พูดถึง Hilt ซึ่งเป็นไลบรารี DI สำหรับ Android พร้อมกับเล่าว่ามันทำงานอย่างไรในกระบวนการพัฒนาแอปพลิเคชันบน Android และสิ่งสำคัญก็คือ มีเคสการใช้งานบางเคสที่พวกเขาได้ลองใช้ซึ่งอาจเป็นประโยชน์สำหรับคุณ เราจึงอยากเล่าให้คุณฟังว่าเป็นอย่างไร
ประโยชน์ของการพัฒนาแอปพลิเคชันบน Android ด้วย Hilt
คุณอาจจะสงสัยว่าทำไมต้องใช้ Hilt ด้วย ต้องขออธิบายก่อนว่า Hilt คือ dependency injection (DI) library สำหรับ Android ที่สร้างขึ้นบน Dagger เพื่อใช้ประสิทธิภาพของ Dagger ทั้งในด้านความแม่นยำของเวลาในการ compile เวลาที่ใช้ในการประมวลผล ความสามารถในการขยายขอบเขตการใช้งาน และการรองรับการใช้งานบน Android Studio ซึ่ง Hilt ช่วยให้การนำ dependency injection หรือการส่งต่อ dependency แทนการสร้างขึ้นมาใหม่ ของ Dagger มาผนวกรวมกับแอปพลิเคชันบน Android เป็นเรื่องง่ายขึ้น
ด้วยเหตุนี้ บริษัทมากมายจึงเริ่มหันมาใช้ Hilt กับแอปพลิเคชันบน Android ของพวกเขามากขึ้นเพราะสามารถรันได้เสถียรและใช้งานง่ายกว่านั่นเอง
และนี่คือตัวอย่างประโยชน์ที่ได้จากการใช้งาน Hilt
การทำงานร่วมกับ Jetpack
- ส่งต่อ ViewModel object ได้ด้วย Hilt
- ทำงานร่วมกับ navigation library ของ Jetpack ได้
- ทำงานร่วมกับ Jetpack Compose ได้
- ส่งต่อ WorkManager ได้ด้วย Hilt
ติดตั้งง่าย
นักพัฒนาสามารถเพิ่ม dependencies เหล่านี้เข้าไปในไฟล์ gradle ที่อยู่ในระดับ app level ได้ ด้วยคำสั่งต่อไปนี้
// Hilt
implementation "com.google.dagger:hilt-android:2.38.1"
kapt "com.google.dagger:hilt-compiler:2.38.1"
implementation 'androidx.hilt:hilt-navigation-fragment:1.0.0'
// Hilt tests
testImplementation 'com.google.dagger:hilt-android-testing:2.38.1'
kaptTest 'com.google.dagger:hilt-android-compiler:2.38.1'
// Hilt UI tests
androidTestImplementation 'com.google.dagger:hilt-android-testing:2.38.1'
kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.38.1'
หลังจากนั้น Hilt ก็จะพร้อมใช้งานและสามารถใช้ annotation เหล่านี้ได้
- @HiltAndroidApp – สำหรับ class ของแอปพลิเคชัน
- @AndroidEntryPoint – Activity หรือ Fragment สำหรับการส่งต่อ
- @HiltViewModel – สำหรับ ViewModel
Hilt เป็น Compile time DIหมายความว่ามันไม่มี instantiation ในระหว่างประมวลผล ซึ่งทำให้
การทดสอบง่ายขึ้น ด้วยการใช้เพียงแค่ 1 annotation ซึ่งก็คือ @HiltAndroidTest
…แต่ยังมีข้อเสียบางอย่าง นั่นคือ
-
ไม่รองรับการทำงานของ FragmentScenario ดังนั้น การทดสอบ UI จึงจำเป็นต้องใช้ boilerplate แต่ Google ก็มีวิธีแก้ไขเรื่องนี้แล้ว
-
Log ไม่ชัดเจนทำให้การ debug ยากขึ้น
กระบวนการทำงานของ Hilt
มาดูกันว่า annotation ต่างๆ ของ Hilt ทำงานร่วมกันเพื่อสร้างโค้ดอย่างไร
จากบทความแนะนำการพัฒนาแบบ MAD หรือ Modern Android Development ที่เราได้ข้อมูลมาจาก Android developer ผู้เชี่ยวชาญ ทำให้เรารู้ว่า Hilt ใช้ annotation processor สำหรับการสร้างโค้ด ดังนั้น เมื่อแปลงซอร์สไฟล์เป็น Java bytecode แล้ว compiler จะทำการประมวลผล annotation ซึ่ง annotation ที่อยู่ในซอร์สไฟล์จะไป activate การทำงานของ annotation processor อย่างที่ชื่อของมันบอกไว้นั่นเอง
หลังจากนั้น พวกมันจะทำการตรวจสอบ annotation และ type เพื่อควบคุมกิจกรรมต่างๆ อย่างเช่น การสร้างและตรวจสอบซอร์สใหม่ๆ เป็นต้น
คุณสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับกระบวนการทำงานของ Hilt และ Dagger ได้จากคลิปวิดีโอเกี่ยวกับทักษะการทำ MAD
Component ต่างๆ ของ Hilt และวงจรชีวิตของพวกมัน
Hilt แตกต่างจาก Dagger ตรงที่มี component ที่กำหนดมาให้แล้วและ builtin อยู่ในตัวมันเอง พร้อมด้วย scope annotation เพื่อให้นักพัฒนาสามารถส่งต่อไปยัง component ของแอปพลิเคชัน Android ตามลำดับวงจรชีวิตอย่าง Activity, Fragment หรือ viewModel เป็นต้น ได้อย่างอัตโนมัติ
แผนภูมิและตัวอย่างโค้ดด้านล่างนี้จะแสดงให้เห็นลำดับชั้น component ของ Hilt
scope annotation ที่อยู่เหนือแต่ละ component แสดงให้เห็นถึง scope ของ binding ต่างๆ ที่เกี่ยวข้องกับอายุของ component และลูกศรที่อยู่ข้างล่างแต่ละ component จะชี้ไปยัง child component อีกที ซึ่ง binding ในตัว child component นั้น โดยปกติแล้วสามารถขึ้นอยู่กับ binding อันใดก็ได้ของ component ที่อยู่ก่อนหน้า
เมื่อพูดถึงอายุของ component แล้ว มีความเกี่ยวข้องที่สำคัญระหว่างอายุของ component กับอายุของ binding อยู่ โดยในกระบวนการสร้างและทำลาย component นั้นจะไปจำกัดอายุของ binding ที่กำกับอยู่ นอกจากนี้ ยังแสดงเวลาที่เหมาะสมเพื่อใช้งาน value ที่ member ทั้งหลายส่งต่อไปด้วย
ในตารางด้านล่างนี้ คุณจะเห็นว่าแต่ละ scope annotation ของ component และอายุที่กำหนดไว้เป็นอย่างไร
เพิ่มโมดูลของ Hilt ได้ง่ายๆ
โมดูลของ Hilt คือคลาสที่อ้างอิงด้วย annotation @Module ซึ่งผู้ใช้สามารถใช้ annotation เพิ่มเติมอย่าง @InstallIn เพื่อกำหนดว่า component ไหนของ Hilt ที่จะไปอยู่ในกระบวนการติดตั้งของโมดูลนั้นๆ
ขั้นตอนในการเพิ่มโมดูลนั้นไม่ซับซ้อน โดยหลักการแล้ว นักพัฒนาจำเป็นต้องสร้าง annotation สำหรับคลาสของโมดูลด้วย @Module และระบุชื่อ component ที่ต้องการติดตั้งโมดูลลงไป สามารถดูตัวอย่างได้จาก Interfaces ในรูปข้างล่างนี้
หากคุณใช้งาน repositories อยู่ คุณสามารถใช้ annotation อย่าง @Binds ได้ ในส่วนของ Providers นั้นหากคุณมี builder จากไลบรารีอื่นอย่าง Retrofit หรือ Moshi คุณก็สามารถใช้ annotation ที่ชื่อ @Provides ได้
ทดสอบการติดตั้ง
สิ่งที่ต้องทำต่อมาก็คือการทดสอบ ก่อนที่จะใช้งาน HiltTestApplication ได้นั้น นักพัฒนาต้องสร้าง test runner ใหม่ขึ้นมาเสียก่อน เจ้าสิ่งนี้จะทำให้ Hilt สามารถทดสอบด้วย instrumented test ทั้งหมดในโปรเจกต์ได้
ในขั้นแรก สร้างคลาส CustomTestRunner ขึ้นมาเพื่อขยายความสามารถของ AndroidJUnitRunner จากนั้น override ด้วยฟังก์ชัน newApplication และส่งชื่อของ HiltTestApplication ไปยังคลาสที่สร้างขึ้นมา ขั้นตอนต่อไป ตั้งค่า test runner ในไฟล์ Gradle เพื่อให้แน่ใจว่า classpath ทั้งหมดมีการนำไปใช้งาน
ในระหว่างการทดสอบ จะมีบางกรณีที่นักพัฒนาต้องการแทนที่บางโมดูล ดังนั้น หากระบบออกแบบมาให้นักพัฒนาสามารถแทนที่ binding ใน production ด้วย binding ปลอม หรือ binding ที่เป็นแบบจำลองได้ ก็จะมีประโยชน์มาก เพื่อให้การทดสอบนั้นไม่ได้รับผลกระทบจากปัจจัยภายนอกหรือกำหนดกฎเกณฑ์ได้ง่ายขึ้น
การจะทำแบบนั้นได้ นักพัฒนาต้องสร้างโมดูลสำหรับทดสอบแยกออกมาพร้อมกับ annotate ด้วย @TestInstallIn นอกจากนั้นยังต้องระบุ component ของโมดูลที่ว่า และโมดูลที่จะไปแทนที่ให้ชัดเจนด้วย
การถอนการติดตั้งโมดูลของ @InstallIn ใน production สำหรับการทดสอบแต่ละอย่าง นักพัฒนาควรจัดการกับการทดสอบที่ใช้ annotation @UninstallModules หลังจากที่ลบออกแล้วจึงจะสามารถติดตั้ง binding ใหม่เฉพาะสำหรับการทดสอบนั้นๆ ได้
อย่างไรก็ดี การแทนที่โมดูลในการทดสอบแต่ละอย่างนั้นยังมีข้อเสียอยู่เหมือนกัน ได้แก่
- อาจมี error ในการ compile ถ้าหากนักพัฒนาพยายามถอนการติดตั้งโมดูลที่ไม่ได้ annotate ด้วย @InstallIn
- นอกจากนั้น พวกเขาสามารถลบโมดูล @InstallIn ได้เพียงแค่ใช้ @UninstallModules โดยไม่ต้องใช้โมดูล @TestInstallIn
- เนื่องจาก Hilt จะสร้าง component ใหม่สำหรับการทดสอบที่ใช้ @UninstallModules ซึ่งอาจส่งผลกระทบรุนแรงต่อ build time ของ unit test ได้ ดังนั้น ควรใช้นานๆ ครั้งและควรใช้ @TestInstallIn เพื่อแทนที่ binding ในทุกคลาสสำหรับการทดสอบจะดีกว่า
วิธีจัดการกับ FragmentScenario
FragmentScenario มี API เพื่อทดสอบยูสเซอร์อินเทอร์เฟซของ fragment ซึ่งมันจะทำงานโดยอัตโนมัติร่วมกับ arbitrary fragment ในทุกเวอร์ชันของ Android framework
มีขั้นตอนบางอย่างที่ต้องทำในการนำ FragmentScenario ไปใช้งาน ดังต่อไปนี้
ขั้นที่ 1: เพิ่ม HiltTestActivity (debug) และ AndroidManifest.xml (debug) ที่ว่างเปล่าเข้าไป
ขั้นที่ 2: ใช้ฟังก์ชันHiltExt พร้อมกับ launchFragmentInHiltContainer extension เพื่อเริ่มการทำงาน fragment ใน container
ขั้นที่ 3:รันการทดสอบได้เลย
แชร์เรื่องนี้
- FinTech (11)
- การพัฒนาซอฟต์แวร์ (10)
- Expert Spotlight (8)
- อาชีพการงาน (8)
- Cloud (5)
- InsurTech (5)
- Mixpanel (5)
- Agile (4)
- Digital Transformation (4)
- JavaScript (4)
- QA (4)
- Trend (4)
- การพัฒนาแอปพลิเคชัน iOS (4)
- Android Developer (3)
- Azure (3)
- Banking (3)
- CSR (3)
- Hybrid App (3)
- IoT (3)
- Product-Centric Mindset (3)
- Seven Peaks Insights (3)
- Thought Leadership (3)
- การพัฒนาแอปฯ Android (3)
- การออกแบบ UX (3)
- บริษัท (3)
- เทคโนโลยีการเงินและการธนาคาร (3)
- .NET (2)
- AI (2)
- Cross-Platform Application (2)
- Data (2)
- Kotlin (2)
- Native App (2)
- ReactJS (2)
- digital marketing (2)
- การพัฒนาแอปฯ (2)
- งาน Product Owner (2)
- 5g (1)
- Android (1)
- AndroidX Biometric (1)
- Azure OpenAI Service (1)
- Biometrics (1)
- CI/CD (1)
- Customer Data Platform (1)
- Data and Analytics (1)
- Design Thinking (1)
- DevOps (1)
- Digital Healthcare (1)
- Digital ID (1)
- Digital Landscape (1)
- Digital Product (1)
- Digital Product Development (1)
- E-payment (1)
- E-wallet (1)
- Financial Inclusion (1)
- GraphQL (1)
- IT Outsourcing (1)
- MVP (1)
- MVVM (1)
- Metaverse (1)
- Morphosis (1)
- Node.js (1)
- Partner (1)
- Platform Engineering (1)
- Product Growth (1)
- Recruitment (1)
- SCB (1)
- SEO (1)
- Scrum Master (1)
- Software Engineer (1)
- Software Tester (1)
- Stripe (1)
- Swift (1)
- SwiftUI (1)
- Tech Meetup (1)
- Turnkey (1)
- UI (1)
- UX (1)
- UX Design (1)
- UX writing (1)
- Web-Debugging Tool (1)
- customer centric (1)
- iOS17 (1)
- waterfall (1)
- การจ้างงาน (1)
- การพัฒนาด้วย RabbitMQ (1)
- การพัฒนาระบบคลาวด์ (1)
- การออกแบบ Decorator Pattern (1)
- การใช้งาน C# (1)
- งาน Product Manager (1)
- งาน platform enginerring (1)
- ทำ Context API (1)
- ฟินเทค (1)
- ระบบการชำระเงิน (1)
- สร้าง brand loyalty (1)
- อีคอมเมิร์ซ (1)
- เขียนโค้ด React (1)
- เทคโนโลยี React (1)
- เพิ่ม conversion (1)
- เฟรมเวิร์ก (1)
- แดชบอร์ด (1)
- พฤศจิกายน 2024 (1)
- สิงหาคม 2024 (1)
- กรกฎาคม 2024 (2)
- มีนาคม 2024 (5)
- กุมภาพันธ์ 2024 (5)
- มกราคม 2024 (14)
- ธันวาคม 2023 (4)
- พฤศจิกายน 2023 (9)
- ตุลาคม 2023 (12)
- กันยายน 2023 (7)
- กรกฎาคม 2023 (4)
- มิถุนายน 2023 (3)
- พฤษภาคม 2023 (3)
- เมษายน 2023 (1)
- มีนาคม 2023 (1)
- พฤศจิกายน 2022 (1)
- สิงหาคม 2022 (4)
- กรกฎาคม 2022 (1)
- มิถุนายน 2022 (4)
- เมษายน 2022 (6)
- มีนาคม 2022 (3)
- กุมภาพันธ์ 2022 (6)
- มกราคม 2022 (3)
- ธันวาคม 2021 (2)
- ตุลาคม 2021 (1)
- กันยายน 2021 (1)
- สิงหาคม 2021 (3)
- กรกฎาคม 2021 (1)
- มิถุนายน 2021 (2)
- พฤษภาคม 2021 (1)
- มีนาคม 2021 (4)
- กุมภาพันธ์ 2021 (4)
- ธันวาคม 2020 (4)
- พฤศจิกายน 2020 (1)
- มิถุนายน 2020 (1)
- เมษายน 2020 (1)