0Pricing
Android Academy · บทเรียน

การฉีด 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ViewModel และ LiveData
  2. ฐานข้อมูล Room
  3. โครูทีนและฟังก์ชัน Suspend
  4. รูปแบบ Repository
  5. คอมโพเนนต์ Navigation
  6. การฉีด Dependency ด้วย Hilt
← กลับไปที่ Android Academy