Hilt 依赖注入使用

Hilt 依赖注入

基础用法

使用@HiltAndroidApp注解Application

kotlin 复制代码
@HiltAndroidApp
class JetpackApp : Application()

使用@AndroidEntryPoint注解Activity

kotlin 复制代码
@AndroidEntryPoint
class TestActivity: ComponentActivity() 

定义被注入的类

kotlin 复制代码
class TestBean @Inject constructor(val testValue: TestValue)

class TestValue @Inject constructor()

注入到Activity中

kotlin 复制代码
@AndroidEntryPoint
class TestActivity: ComponentActivity() {
    @Inject
    lateinit var testBean: TestBean
}

Hilt模块

1.注入接口类型

定义接口和实现类

kotlin 复制代码
interface ITestInterface


class TestInterface @Inject constructor(): ITestInterface

在Module中绑定实现类

kotlin 复制代码
@Module
@InstallIn(ActivityComponent::class)
abstract class HiltModule {

    @Binds
    abstract fun bindITestInterface(
        testInterface: TestInterface //实现接口的实现类
    ): ITestInterface //接口类型

}

在Activity中注入依赖

kotlin 复制代码
    //注入接口依赖
    @Inject
    lateinit var interfaceBean: ITestInterface

2.使用@Provides注入实例

kotlin 复制代码
/**
 * 构造方法不能修改的类
 */
class ProvideTestBean

在模块中提供ProvideTestBean

kotlin 复制代码
@Module
@InstallIn(ActivityComponent::class)
class HiltModule1 {

    @Provides
    fun provideTestBean(): ProvideTestBean {
        return ProvideTestBean()
    }
}

3.为同一类型提供多个绑定

1.定义不同类型的注解

kotlin 复制代码
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AutoTestBean

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherTestBean

2.在模块中使用定义的注解

kotlin 复制代码
@Module
@InstallIn(ActivityComponent::class)
class HiltModule1 {

    @Provides
    @AutoTestBean
    fun provideAutoTestBean(): TypeTestBean {
        return TypeTestBean()
    }

    @Provides
    @OtherTestBean
    fun provideOtherTestBean(): TypeTestBean {
        return TypeTestBean("其他")
    }

}

3.在Activity注入不同的类型

kotlin 复制代码
    //同一类型多个绑定
    @Inject
    @AutoTestBean
    lateinit var autoTestBean: TypeTestBean

    //同一类型多个绑定
    @Inject
    @OtherTestBean
    lateinit var otherTestBean: TypeTestBean

Hilt组件

在模块中使用@InstallIn将模块安装到指定组件中。如上面的例子中使用@InstallIn(ActivityComponent::class)将模块安装到Activity组件中

1.内置组件

2.组件生命周期

Hilt 会按照相应 Android 类的生命周期自动创建和销毁生成的组件类的实例。

3.组件的作用域

默认情况下,Hilt 中的所有绑定都未限定作用域。这意味着,每当应用请求绑定时,Hilt 都会创建所需类型的一个新实例。

Hilt 允许使用注解将绑定的作用域限定为特定组件,限定作用域内注入的依赖都是同一个实例

kotlin 复制代码
 /**
 * 作用域为Activity的被依赖类
 *
 * @constructor Create empty Test bean activity scoped
 */
@ActivityScoped
class TestBeanActivityScoped @Inject constructor()

/**
 * 作用域为全局的被依赖类
 *
 * @constructor Create empty Test bean singleton
 */
@Singleton
class TestBeanSingleton @Inject constructor()
    
/**
 * 在模块中限定作用域
 */
@Provides
@Singleton
fun provideSingletonBean(): SingletonBean {
    return SingletonBean(ProvideTestBean())
}

如果模块安装到子组件,则不允许限定父级的作用域,如@InstallIn(ActivityComponent::class)的模块不允许使用@Singleton,编译会直接报错

4.组件层次结构

将模块安装到组件后,其绑定就可以用作该组件中其他绑定的依赖项,也可以用作组件层次结构中该组件下的任何子组件中其他绑定的依赖项:

如安装到SingletonComponent的可以在整个应用中注入,如ViewModel、Activity、Fragment中注入,安装到ActivityComponent可以在Activity、Fragment中注入,但是安装在FragmentComponent则不可以在Activity中注入

ViewWithFragmentComponent 位于 FragmentComponent 下。FragmentComponent 和 ViewComponent 位于 ActivityComponent 下。ActivityComponent 位于 ActivityRetainedComponent 下。ViewModelComponent 位于 ActivityRetainedComponent 下。ActivityRetainedComponent 和 ServiceComponent 位于 SingletonComponent 下。

5.组件总结(个人理解)

  1. 可以将模块安装到不同组件中,不同组件对应着不同的注入对象
  2. 安装到组件中的模块生命周期和注入对象的生命周期关联,注入对象销毁了才会把依赖对象销毁
  3. 被依赖的对象默认没有限定作用域,可以使用注解限定作用域,限定作用域后会安装到对应的组件
  4. 子组件对应的注入对象内可以注入父组件中提供的依赖项,反过来不可以

6.注入ViewModel

无需自己写factory

kotlin 复制代码
@HiltViewModel
class LoginViewModel @Inject constructor(val userRepository: UserRepository) : ViewModel() 

//注入到Activity
@AndroidEntryPoint
class TestViewModelActivity :FragmentActivity(R.layout.activity_view_model){

    private val mViewModel: TestActivityViewModel by viewModels()
}

//注入到Compose
@Composable
fun LoginScreen(
    navController: NavHostController,
    viewModel: LoginViewModel = hiltViewModel(),
) {
    ......
}
相关推荐
草字6 分钟前
cocos 打包安卓
android
DeBuggggggg1 小时前
centos 7.6安装mysql8
android
浩浩测试一下2 小时前
渗透信息收集- Web应用漏洞与指纹信息收集以及情报收集
android·前端·安全·web安全·网络安全·安全架构
移动开发者1号3 小时前
深入理解原子类与CAS无锁编程:原理、实战与优化
android·kotlin
陈卓4103 小时前
MySQL-主从复制&分库分表
android·mysql·adb
移动开发者1号3 小时前
深入理解 ThreadLocal:原理、实战与优化指南
android·kotlin
zhangphil3 小时前
Android PNG/JPG图ARGB_8888/RGB_565‌解码形成Bitmap在物理内存占用大小的简单计算
android
厦门德仔4 小时前
【WPF】WPF(样式)
android·java·wpf
aqi004 小时前
FFmpeg开发笔记(七十二)Linux给FFmpeg集成MPEG-5视频编解码器EVC
android·ffmpeg·音视频·流媒体
Devil枫6 小时前
Kotlin高级特性深度解析
android·开发语言·kotlin