Hilt 是 Google 基于 Dagger 开发的 Android 专属依赖注入框架,它能显著简化 Android 应用的依赖注入代码。以下是如何使用 Kotlin 结合 Hilt 简化依赖管理的详细指南:
一、快速配置
- 添加 Gradle 依赖
// build.gradle (Module)
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-kapt")
id("com.google.dagger.hilt.android") // 添加 Hilt 插件
}
dependencies {
implementation("com.google.dagger:hilt-android:2.48")
kapt("com.google.dagger:hilt-compiler:2.48")
}
// build.gradle (Project)
buildscript {
dependencies {
classpath("com.google.dagger:hilt-android-gradle-plugin:2.48")
}
}
二、基础用法
1. 初始化 Hilt
@HiltAndroidApp // 必须标记 Application 类
class MyApp : Application()
2. 自动注入 Activity/Fragment
@AndroidEntryPoint // 自动注入标记
class MainActivity : AppCompatActivity() {
@Inject lateinit var myDependency: MyDependency // 字段注入
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myDependency.doSomething() // 直接使用已注入的依赖
}
}
三、依赖模块定义
1. 创建模块
@Module
@InstallIn(SingletonComponent::class) // 作用域为应用生命周期
object AppModule {
@Provides
@Singleton // 单例作用域
fun provideNetworkClient(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.build()
}
}
2. 组件作用域对照表
| 作用域注解 | 对应组件 | 生命周期 |
|---|---|---|
| @Singleton | SingletonComponent | Application |
| @ActivityScoped | ActivityComponent | Activity |
| @FragmentScoped | FragmentComponent | Fragment |
| @ViewScoped | ViewComponent | View |
| @ViewModelScoped | ViewModelComponent | ViewModel |
四、ViewModel 注入
@HiltViewModel
class MyViewModel @Inject constructor(
private val repository: MyRepository
) : ViewModel() {
// ViewModel 逻辑
}
// Activity/Fragment 中使用
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
}
五、高级技巧
1. 限定符 (Qualifiers)
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@AuthInterceptorOkHttpClient
@Provides
fun provideAuthOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(AuthInterceptor())
.build()
}
}
2. 预定义限定符
class MyService @Inject constructor(
@ApplicationContext context: Context, // 应用上下文
@ActivityContext activityContext: Context // 当前 Activity 上下文
)
3. 接口绑定
@Module
@InstallIn(SingletonComponent::class)
interface ServiceModule {
@Binds
fun bindAnalyticsService(
analyticsServiceImpl: AnalyticsServiceImpl
): AnalyticsService
}
六、常见问题解决
-
依赖无法注入
- 检查是否添加了
@AndroidEntryPoint - 确认依赖提供方模块已正确安装到组件
- 验证作用域是否匹配(如 Activity 作用域依赖不能在 Application 作用域模块提供)
- 检查是否添加了
-
循环依赖
// 错误示例 class A @Inject constructor(b: B) class B @Inject constructor(a: A) // 解决方案:使用 Lazy 延迟初始化 class A @Inject constructor(private val b: Lazy<B>)
七、测试支持
@HiltAndroidTest
class ExampleTest {
@get:Rule
val hiltRule = HiltAndroidRule(this)
@Inject
lateinit var testDependency: TestDependency
@Before
fun init() {
hiltRule.inject()
}
@Test
fun testWithInjectedDependencies() {
// 使用注入的测试依赖
}
}
// 测试模块定义
@Module
@TestInstallIn(components = [SingletonComponent::class], replaces = [ProdModule::class])
object TestModule {
@Provides
fun provideTestDependency() = TestDependency()
}
八、优势总结
- 代码简化:相比传统 Dagger 减少 70% 的模板代码
- 作用域管理:自动处理 Android 组件的生命周期
- 可维护性:依赖关系显式声明,便于代码跟踪
- 测试友好:轻松替换测试依赖
对于新项目推荐直接使用 Hilt,现有 Dagger 项目可通过逐步迁移的方式整合。官方文档提供了详细的迁移指南和最佳实践。