以下是一个完整的 Hilt 实战讲解,从基础概念到实际应用,逐步演示如何在 Android 项目中使用 Hilt 进行依赖注入。
Hilt 实战讲解
1. 什么是 Hilt?
Hilt 是 Android 官方推荐的依赖注入(DI, Dependency Injection)框架,基于 Dagger 构建,专为 Android 设计。它简化了 Dagger 的使用,减少了模板代码,使依赖注入更加容易上手。
2. Hilt 的核心概念
依赖注入(DI):将对象的创建和依赖关系交给框架管理,而不是在代码中硬编码。
Hilt 的优势:
减少样板代码。
提高代码的可测试性和可维护性。
与 Android 组件(如 Activity、Fragment、ViewModel)无缝集成。
3. Hilt 实战步骤
3.1 添加依赖
在项目的 build.gradle 文件中添加 Hilt 和其他相关依赖:
// 根项目的 build.gradle
plugins {
id 'com.google.dagger.hilt.android' version '2.44' apply false
}
// 模块的 build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
}
dependencies {
// Hilt
implementation 'com.google.dagger:hilt-android:2.44'
kapt 'com.google.dagger:hilt-compiler:2.44'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// Kotlin 协程
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1'
// Lifecycle 和 ViewModel
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.activity:activity-ktx:1.7.2'
}
3.2 初始化 Hilt
在 Application 类中初始化 Hilt:
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class MyApplication : Application()
3.3 定义依赖项
使用 @Module 和 @Provides 定义需要注入的依赖项。例如,为 Retrofit 提供依赖:
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
@Singleton
fun provideApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}
3.4 定义 API 接口
使用 Retrofit 定义 API 接口:
import retrofit2.http.GET
import retrofit2.http.Path
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") id: Int): User
@GET("users")
suspend fun getUsers(): List<User>
}
3.5 在 ViewModel 中使用 Hilt
使用 @HiltViewModel 注解标记 ViewModel,并通过构造函数注入依赖:
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class UserViewModel @Inject constructor(
private val apiService: ApiService
) : ViewModel() {
private val _userState = MutableStateFlow<Result<User>>(Result.Loading)
val userState: StateFlow<Result<User>> get() = _userState
fun fetchUser(userId: Int) {
viewModelScope.launch {
_userState.value = Result.Loading
_userState.value = NetworkHelper.safeApiCall {
apiService.getUser(userId)
}
}
}
}
3.6 在 Activity/Fragment 中使用 Hilt
使用 @AndroidEntryPoint 注解标记 Activity 或 Fragment,并注入 ViewModel:
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class UserActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user)
// 观察用户数据
viewModel.userState.observe(this) { result ->
when (result) {
is Result.Loading -> showLoading()
is Result.Success -> showUser(result.data)
is Result.Error -> showError(result.exception.message)
}
}
// 发起请求
viewModel.fetchUser(1)
}
private fun showLoading() {
// 显示加载动画
}
private fun showUser(user: User) {
// 更新 UI 显示用户信息
}
private fun showError(message: String?) {
// 显示错误信息
}
}
3.7 封装网络请求工具类
封装一个通用的网络请求工具类,处理协程的异常和加载状态:
sealed class Result<out T> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Throwable) : Result<Nothing>()
object Loading : Result<Nothing>()
}
object NetworkHelper {
suspend fun <T> safeApiCall(apiCall: suspend () -> T): Result<T> {
return try {
Result.Success(apiCall())
} catch (e: Exception) {
Result.Error(e)
}
}
}
4. 运行项目
确保 API 接口可用(如 https://jsonplaceholder.typicode.com/users)。
运行项目,观察 UI 是否正确显示用户数据和加载状态。
5. 总结
通过 Hilt 的依赖注入,我们实现了以下功能:
1.Retrofit 的依赖注入,简化了网络请求的配置。
2.ViewModel 的依赖注入,确保 UI 与数据分离。
3.统一的错误处理和加载状态管理。
4.减少了模板代码,提高了代码的可读性和可维护性。
Hilt 是 Android 开发中依赖注入的最佳实践,特别适合中大型项目。通过本文的实战讲解,你可以快速上手 Hilt,并将其应用到实际项目中。