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(),
) {
    ......
}
相关推荐
恋猫de小郭25 分钟前
iOS 26 正式版即将发布,Flutter 完成全新 devicectl + lldb 的 Debug JIT 运行支持
android·前端·flutter
幻雨様1 小时前
UE5多人MOBA+GAS 54、用户登录和会话创建请求
android·ue5
Just_Paranoid1 小时前
【SystemUI】锁屏来通知默认亮屏Wake模式
android·framework·systemui·keyguard·aod
没有了遇见1 小时前
Android +,++,+= 的区别
android·kotlin
_无_妄_3 小时前
Android 使用 WebView 直接加载 PDF 文件,通过 JS 实现
android
VomPom3 小时前
手写一个精简版Koin:深入理解依赖注入核心原理
android
IT乐手3 小时前
Java 编写查看调用栈信息
android
Digitally4 小时前
如何轻松永久删除 Android 手机上的短信
android·智能手机
JulyYu4 小时前
Flutter混合栈适配安卓ActivityResult
android·flutter
Warren985 小时前
Appium学习笔记
android·windows·spring boot·笔记·后端·学习·appium