Android依赖注入框架Hilt入门指南
什么是Hilt?
Hilt是Google基于Dagger开发的Android专属依赖注入(Dependency Injection)框架,它简化了Dagger在Android应用中的使用,减少了大量模板代码,让依赖注入变得更加简单高效。
依赖注入是一种设计模式,它允许类从外部源获取其依赖项,而不是自己创建它们。这带来了以下优势:
代码解耦,提高可测试性
易于重用代码和依赖项
简化复杂对象的创建和管理
便于单元测试和模块化开发
Hilt的核心概念
1. @HiltAndroidApp
所有使用Hilt的应用都必须包含一个用@HiltAndroidApp
注解的Application类。这会触发Hilt的代码生成,包括一个应用级别的依赖容器。
@HiltAndroidApp
class MyApplication : Application()
2. @AndroidEntryPoint
Hilt提供了几个预定义的Android组件入口点,你可以在这些组件中使用依赖注入:
@AndroidEntryPoint
class MainActivity : AppCompatActivity()@AndroidEntryPoint
class MyFragment : Fragment()@AndroidEntryPoint
class MyService : Service()
3. @Inject
使用@Inject
注解标记构造函数,告诉Hilt如何提供该类型的实例:
class AnalyticsAdapter @Inject constructor(private val service: AnalyticsService
) { /* ... */ }
4. 模块和@Provides
当无法通过构造函数注入时(例如接口或来自外部库的类),可以使用Hilt模块。模块是一个带有@Module
注解的类,它告诉Hilt如何提供某些类型的实例。
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {@Providesfun provideAnalyticsService(): AnalyticsService {return Retrofit.Builder().baseUrl("https://example.com").build().create(AnalyticsService::class.java)}
}
@InstallIn
指定了模块的作用域,常见的组件作用域包括:
ApplicationComponent
ActivityComponent
FragmentComponent
ViewComponent
ServiceComponent
Hilt的依赖注入实践
基本注入
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {@Inject lateinit var analytics: AnalyticsAdapteroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)analytics.sendEvent("ActivityCreated")}
}
限定符
当同一类型有多个可能的依赖项时,可以使用限定符:
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient@Module
@InstallIn(ApplicationComponent::class)
object NetworkModule {@AuthInterceptorOkHttpClient@Providesfun provideAuthInterceptorOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient {return OkHttpClient.Builder().addInterceptor(authInterceptor).build()}@OtherInterceptorOkHttpClient@Providesfun provideOtherInterceptorOkHttpClient(otherInterceptor: OtherInterceptor): OkHttpClient {return OkHttpClient.Builder().addInterceptor(otherInterceptor).build()}
}
作用域
默认情况下,Hilt中的所有绑定都是未限定作用域的,每次请求都会创建一个新实例。要限定作用域,可以使用作用域注解:
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {@ActivityScoped@Providesfun provideAnalyticsService(analyticsServiceImpl: AnalyticsServiceImpl): AnalyticsService {return analyticsServiceImpl}
}
常见的作用域注解:
@Singleton - 应用级别单例
@ActivityScoped - Activity级别单例
@FragmentScoped - Fragment级别单例
@ViewScoped - View级别单例
Hilt与ViewModel
Hilt提供了对ViewModel的特殊支持:
@HiltViewModel
class MyViewModel @Inject constructor(private val savedStateHandle: SavedStateHandle,private val repository: MyRepository
) : ViewModel() {// ViewModel code
}@AndroidEntryPoint
class MyActivity : AppCompatActivity() {private val viewModel: MyViewModel by viewModels()// ...
}
测试中的Hilt
Hilt提供了专门的测试支持:
@HiltAndroidTest
class ExampleInstrumentedTest {@get:Rulevar hiltRule = HiltAndroidRule(this)@Injectlateinit var analyticsAdapter: AnalyticsAdapter@Testfun testAnalyticsAdapter() {hiltRule.inject()assertThat(analyticsAdapter).isNotNull()}
}
Hilt的优势
简化Dagger使用:Hilt自动生成大量Dagger样板代码
预定义组件:为Android组件提供标准化的组件和作用域
与Jetpack集成:完美支持ViewModel、WorkManager等Jetpack组件
减少错误:编译时验证依赖关系,减少运行时错误
测试友好:提供专门的测试支持
总结
Hilt作为Android官方推荐的依赖注入解决方案,极大地简化了Dagger在Android应用中的使用。通过自动生成代码和提供标准化的组件,开发者可以更专注于业务逻辑而不是依赖管理。随着应用的复杂度增加,Hilt的优势会越发明显,特别是在大型项目和团队协作中。
要开始使用Hilt,只需在项目的build.gradle中添加Hilt插件依赖,并在模块的build.gradle中添加必要的依赖项即可。Google官方文档提供了详细的迁移指南和最佳实践,是深入学习Hilt的优秀资源。