官方文档
项目根目录build.gradle
buildscript {
ext {
hiltVersion = "2.36"
}
dependencies {
//Hilt
classpath "com.google.dagger:hilt-android-gradle-plugin:$hiltVersion"
}
}
模块目录build.gradle
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation "com.google.dagger:hilt-android:$hiltVersion"
kapt "com.google.dagger:hilt-android-compiler:$hiltVersion"
}
@HiltAndroidApp
@HiltViewModel
说明:其他入口点使用@AndroidEntryPoint
注解
@InstallIn(ActivityComponent::class)
表示将这个模块安装到Activity组件中。
@InstallIn(ApplicationComponent::class)
可以将视力放在全项目中使用。
Hilt组件 | 注入的对象 |
---|---|
SingletonComponent | Application |
ActivityRetainedComponent | N/A |
ViewModelComponent | ViewModel |
ActivityComponent | Activity |
FragmentComponent | Fragment |
ViewComponent | View |
ViewWithFragmentComponent | 带有@WithFragmentBindings 注释的View |
ServiceFragment | Service |
Hilt会按照响应Android类的生命周期自动创建和销毁生成的组件类的实例。
Hilt组件 | 创建时机 | 销毁时机 |
---|---|---|
SingletonComponent | Application#onCreate() | Application@onDestroy() |
ActivityRetainedComponent | Activity#onCreate() | Activity#onDestroy() |
ViewModelComponent | ViewModel被创建 | ViewModel被销毁 |
ActivityComponent | Activity#onCreate() | Activity#onDestroy() |
FragmentComponent | Fragment#onAttach() | Fragment#onDestroy() |
ViewComponent | View#super() | 视图被销毁 |
ViewWithFragmentComponent | View#super() | 视图被销毁 |
ServiceComponent | Service#onCreate() | Service#onDestroy() |
每当应用请求绑定时,Hilt都会创建所需类型的一个新实例。
Hilt允许将绑定的作用域限定为特定组件。Hilt只为绑定作用域限定到的组件的每个实例创建一次限定作用域的绑定,对该绑定的所有请求共享同一实例。
如:@Singleton
表示全局单例,@ActivityScoped
表示在同一Activity范围内共享一个实例。
Hilt组件 | Android类 | 作用域 |
---|---|---|
SingletonComponent | Application | @Singleton |
ActivityRetainedComponent | Activity | @ActivityRetainedScoped |
ViewModelComponent | ViewModel | @ViewModelScoped |
ActivityComponent | Activity | @ActivityScoped |
FragmentComponent | Fragment | @FragmentScoped |
ViewComponent | View | @ViewScoped |
ViewWithFragmentComponent | 带有@WithFragmentBindings 注释的View |
@ViewScoped |
ServiceComponent | Service | @ServiceScoped |
对某个类声明了某种作用域注解之后,这个注解的箭头所能指到的地方,都可以对该类进行依赖注入,同时在该范围内共享同一个实例。
在Hilt中,必须定义一个Application,使用@HiltAndroidApp
注解
@HiltAndroidApp
class BaseApp : Application() {
}
@AndroidEntryPoint注解
定义Activity为注入点@Inject
注解在user字段上,表示通过Hilt注入@Inject
注解,表示通过构造函数创建一个对象@Inject
注解的字段不能为privateclass User @Inject constructor(){
}
使用
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var user: User
@Inject
lateinit var user2: User
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
log("$user") //com.example.hiltdemo.User@d4f5027
log("$user2") //com.example.hiltdemo.User@a5b32d4
}
}
class Car @Inject constructor(val user: User) {
fun drive() {
log("$user 正在开车")
}
}
使用
@Inject
lateinit var car: Car
car.drive() //User@77b6f83 正在开车
@Binds
注解提供依赖注入的对象interface Engine {
fun start()
fun shutdown()
}
class GasEngine @Inject constructor() : Engine {
override fun start() {
log("燃油引擎 start")
}
override fun shutdown() {
log("燃油引擎 shutdown")
}
}
class ElectricEngine @Inject constructor() : Engine {
override fun start() {
log("电力引擎 start")
}
override fun shutdown() {
log("电力引擎 shutdown")
}
}
@Module
@InstallIn(ActivityComponent::class)
abstract class EngineModule {
@Binds
abstract fun bindEngine(gasEngine: GasEngine): Engine
}
使用
class Car @Inject constructor(val user: User) {
@Inject
lateinit var engine: Engine
fun drive() {
engine.start()
log("$user 正在开车")
engine.shutdown()
}
}
@Qualifier
注解分别定义2个注解:BindGasEngine、BindElectricEngine@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class BindGasEngine
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class BindElectricEngine
@Module
@InstallIn(ActivityComponent::class)
abstract class SelectEngineModule {
@BindGasEngine
@Binds
abstract fun bindGasEngine(gasEngine: GasEngine): Engine
@BindElectricEngine
@Binds
abstract fun bindElectricEngine(electricEngine: ElectricEngine): Engine
}
使用
class Car @Inject constructor(val user: User) {
@BindGasEngine
@Inject
lateinit var gasEngine: Engine
@BindElectricEngine
@Inject
lateinit var electricEngine: Engine
}
@Provides
注解提供对象@Module
@InstallIn(SingletonComponent::class)
class NetworkModule {
@Singleton
@Provides
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.build()
}
@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl("https://wanandroid.com/")
.build()
}
}
使用
@Inject
lateinit var okHttpClient: OkHttpClient
@Inject
lateinit var retrofit: Retrofit
Hilt提供了@ApplicationContext
和@ActivityContext
内置注解,会自动提供一个Application类型和Activity类型的Context传入
class MyContext @Inject constructor(
@ApplicationContext val conext: Context,
@ActivityContext val activityContext: Context
)
@Inject
lateinit var myContext: MyContext
log("myContext : ${myContext.conext} ${myContext.activityContext}")
每个Hilt组件都默认绑定的对象,如:在ActivityComponent组件中,默认绑定Application/Activity
class MyContext2 @Inject constructor(
val application: Application,
val activity: Activity
)
@Inject
lateinit var myContext2:
log("myContext2 : ${myContext2.application} ${myContext2.activity}")
@ActivityRetainedScoped
注解,在ViewModel的构造函数里添加仓库层的依赖仓库层
class Repository @Inject constructor() {
fun getData() = "从仓库获取了数据"
}
ViewModel层
@HiltViewModel
class MyViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val repository: Repository
) : ViewModel() {
private val liveData = MutableLiveData<String>()
fun loadData(): MutableLiveData<String> {
viewModelScope.launch {
delay(5000L)
liveData.value = repository.getData()
}
return liveData
}
}
View层
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<MyViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.loadData().observe(this) {
log(it)
}
}
}