การฉีด Dependency ด้วย Hilt
ทำให้การจัดการ dependency ง่ายขึ้นด้วย Hilt ใช้ @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel, @Module, @Provides และขอบเขต @Singleton
การฉีด Dependency ด้วย Hilt เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 6 จากทั้งหมด 6 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 6 บทเรียน
การฉีดการพึ่งพาคืออะไร
การฉีดการพึ่งพา (DI) หมายถึงการจัดเตรียมสิ่งที่ออบเจ็กต์ต้องใช้ให้ แทนที่จะให้ออบเจ็กต์สร้างการพึ่งพาเหล่านั้นเอง
หากไม่มี DI คลาสจะสร้างการพึ่งพาของตัวเอง ทำให้ผูกติดกันแน่นและทดสอบได้ยาก เมื่อใช้ DI การพึ่งพาจะถูก ฉีดจากภายนอก ทำให้ผูกกันอย่างหลวม ทดสอบได้ง่าย และสลับใช้งานได้สะดวก
DI แบบทำเองเทียบกับฮิลต์
DI แบบทำเองใช้งานได้ แต่จะยุ่งยากเมื่อโครงการมีขนาดใหญ่ขึ้น:
// Manual DI — you create and pass everything:
val db = AppDatabase.getInstance(context)
val dao = db.userDao()
val repo = UserRepository(dao)
val factory = UserViewModel.Factory(repo)
val viewModel = ViewModelProvider(this, factory)[UserViewModel::class.java]
// With Hilt:
// Just annotate, Hilt does the wiring
@HiltViewModel
class UserViewModel @Inject constructor(private val repo: UserRepository) : ViewModel()การเพิ่มฮิลต์
เพิ่มฮิลต์ลงในโครงการของคุณ:
// project/build.gradle:
buildscript {
dependencies {
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.51'
}
}
// app/build.gradle:
plugins {
id 'com.google.dagger.hilt.android'
id 'kotlin-kapt'
}
dependencies {
implementation 'com.google.dagger:hilt-android:2.51'
kapt 'com.google.dagger:hilt-android-compiler:2.51'
}@HiltAndroidApp
ใส่คำอธิบายประกอบ @HiltAndroidApp ให้กับคลาส Application ของคุณ นี่คือจุดเริ่มต้นของลำดับชั้นคอมโพเนนต์ฮิลต์:
@HiltAndroidApp
class MyApp : Application()
// Also register in AndroidManifest.xml:
// <application android:name=".MyApp" ...>@AndroidEntryPoint
เพิ่ม @AndroidEntryPoint ให้กับ Activity, Fragment และ Service ที่ต้องใช้การพึ่งพาที่ถูกฉีด:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var analytics: AnalyticsService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
analytics.logEvent("app_open")
}
}
@AndroidEntryPoint
class HomeFragment : Fragment() {
// Fragment's parent Activity must also be @AndroidEntryPoint
}@Inject — การฉีดผ่านตัวสร้าง
ทำเครื่องหมายตัวสร้างด้วย @Inject เพื่อบอกฮิลต์ว่าจะสร้างคลาสอย่างไร ฮิลต์จะจัดการพารามิเตอร์ทั้งหมดให้โดยอัตโนมัติ:
class UserRepository @Inject constructor(
private val userDao: UserDao,
private val apiService: ApiService
) {
suspend fun getUsers() = userDao.getAll()
suspend fun syncFromNetwork() {
val users = apiService.fetchUsers()
userDao.insertAll(users)
}
}
// Hilt sees UserRepository needs UserDao and ApiService,
// and automatically creates and injects them.@HiltViewModel
ใส่คำอธิบายประกอบ @HiltViewModel ให้กับ ViewModel และใช้ @Inject constructor ใน Fragment ให้รับอินสแตนซ์ด้วย by viewModels():
@HiltViewModel
class UserViewModel @Inject constructor(
private val repo: UserRepository
) : ViewModel() {
val users = repo.getUsersFlow().asLiveData()
}
// In Fragment:
@AndroidEntryPoint
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels() // Hilt provides it
}@Module และ @Provides
เมื่อฮิลต์ใช้การฉีดผ่านตัวสร้างไม่ได้ (เช่น อินเทอร์เฟซหรือคลาสจากภายนอก) ให้จัดเตรียมอินสแตนซ์ผ่าน @Module:
@Module
@InstallIn(SingletonComponent::class) // lives for app lifetime
object NetworkModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
@Singleton
fun provideApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}@Binds — การผูกอินเทอร์เฟซ
ใช้ @Binds เพื่อบอกฮิลต์ว่าควรใช้งานการนำไปใช้แบบใดสำหรับอินเทอร์เฟซหนึ่ง:
interface AnalyticsService {
fun logEvent(name: String)
}
class FirebaseAnalytics @Inject constructor() : AnalyticsService {
override fun logEvent(name: String) { /* Firebase impl */ }
}
@Module
@InstallIn(SingletonComponent::class)
abstract class AnalyticsModule {
@Binds
@Singleton
abstract fun bindAnalytics(impl: FirebaseAnalytics): AnalyticsService
}ขอบเขตของฮิลต์
ขอบเขตจะควบคุมว่าอินสแตนซ์ที่ถูกฉีดจะมีอายุการใช้งานนานเท่าใด:
@Singleton— มีอินสแตนซ์เดียวตลอดอายุการใช้งานของแอป (ApplicationComponent)@ActivityRetainedScoped— คงอยู่แม้มีการเปลี่ยนแปลงการกำหนดค่า@ActivityScoped— หนึ่งอินสแตนซ์ต่อ Activity@FragmentScoped— หนึ่งอินสแตนซ์ต่อ Fragment@ViewModelScoped— หนึ่งอินสแตนซ์ต่อ ViewModel
การทดสอบด้วยฮิลต์
แทนที่การพึ่งพาจริงด้วยตัวจำลองในการทดสอบ โดยใช้การรองรับการทดสอบของฮิลต์:
@HiltAndroidTest
class UserRepositoryTest {
@get:Rule
val hiltRule = HiltAndroidRule(this)
@Inject
lateinit var repo: UserRepository
@Before
fun setUp() {
hiltRule.inject()
}
@Test
fun usersAreFetched() {
assertNotNull(repo)
}
}ตรวจสอบอย่างรวดเร็ว
คำอธิบายประกอบใดบอกให้ฮิลต์สร้างลำดับชั้นคอมโพเนนต์ DI สำหรับแอปพลิเคชันทั้งหมด
ทบทวน: การฉีดการพึ่งพาด้วยฮิลต์
ฮิลต์ทำให้ DI ใน Android เกือบเป็นอัตโนมัติ:
@HiltAndroidAppบนคลาส Application@AndroidEntryPointบน Activity และ Fragment@Inject constructorสำหรับคลาสที่รองรับการฉีด@HiltViewModel+@Inject constructorสำหรับ ViewModel@Module+@Providesสำหรับคลาสและอินเทอร์เฟซจากภายนอก@Singletonเพื่อใช้อินสแตนซ์เดียวร่วมกันทั้งแอป
ถัดไป: การแจ้งเตือนแบบพุชด้วย Firebase Cloud Messaging
คำถามที่พบบ่อย
บทเรียน “การฉีด Dependency ด้วย Hilt” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การฉีด Dependency ด้วย Hilt” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 6 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การฉีด Dependency ด้วย Hilt”
ทำให้การจัดการ dependency ง่ายขึ้นด้วย Hilt ใช้ @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel, @Module, @Provides และขอบเขต @Singleton คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 6 จากทั้งหมด 6 บทเรียน
บทเรียน “การฉีด Dependency ด้วย Hilt” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ViewModel และ LiveData
- ฐานข้อมูล Room
- โครูทีนและฟังก์ชัน Suspend
- รูปแบบ Repository
- คอมโพเนนต์ Navigation
- การฉีด Dependency ด้วย Hilt