Hilt的基本用法

如果没了解过Dagger,那就直接开始学Hilt吧,比Dagger容易上手使用,而且Hilt是基于Dagger2开发的。
在开始学习之前,先搞清楚为什么要用它,能带来什么好处?

作用:解耦

之前有说过APT(annotation processing tool)也有解耦的作用,通过自定义注解,获取到被注解的类/方法/变量信息,从而实现在两个独立的Module之前实现Activity跳转的功能。

关系:Hilt的实现依赖APT技术

Hilt可以通过注解的方式将所需对象传入到另一个类当中,避免了我们自己new对象,但前题是要告诉Hilt怎么去创建对象。

所以学习Hilt,就是告诉Hilt怎么去创建我们所需的对象

补充一点:在一个类中使用另外的对象,通常要怎么get到它?

  1. new 对象
  2. 构造方法传参

这两种引用方式都可通过Hilt提供的@Inject注解来实现。

Ok,接下来配置Hilt的使用环境:

  1. 工程级gradle下引入hilt插件:
buildscript {
    ext {
        compose_version = '1.2.0'
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
	...
    id 'com.google.dagger.hilt.android' version '2.44' apply false //引入Hilt插件
}
  1. 项目级gradle下,引入kapt和Hilt插件
plugins {
    ...
    //在项目级gradle中引入以下两个插件
    id 'kotlin-kapt'
    id 'com.google.dagger.hilt.android'
}
  1. 在项目依赖中引入Hilt
dependencies {
	...
    implementation "com.google.dagger:hilt-android:2.44"
    kapt "com.google.dagger:hilt-compiler:2.44"
}
  1. 允许引用来生成代码。与android{}平级写入
// Allow references to generated code
kapt {
    correctErrorTypes true
}

通过以上4步,就将使用Hilt的环境配置完毕。

使用之前,首先用@HiltAndroidApp对Application进行注解,相当于Hilt的初始化吧

@HiltAndroidApp
class MyApplication: Application(){
}

同样的,如果要在
Activity
Fragment
Service
Broadcast
View
中使用,也都需要对类先进行注解,不过注解名称与Applicaion不同:@AndroidEntryPoint

Hilt的一些用法

  • 自有类的引入:
//对于普通类,直接通过在构造方法添加@Inject来注入
class MyTest @Inject constructor() {
    fun print(): Unit {
        Log.i(">>>", "直接通过构造方法来注入,获取实例!")
    }
}

可以明显看到,用@Inject注解修饰了主构造方法,这就告诉Hilt,用该构造方法来创建该类的对象供其他地方调用。
在Activity中要引用该类实例时,同样用@Inject注解成员变量:

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject lateinit var myTest: MyTest

    override fun onCreate(savedInstanceState: Bundle?) {
		...
        myTest.print()
    }
}
  • 如果成员变量或构造入参的类型是一个接口或抽象类呢?其实说的意思是没有构造方法用来注解,那只能注解子类的构造方法并提供其实现类了。所以有两步需要做:
    1. 提供其注解构造方法的子类(实现类);
    2. 告诉Hilt用这个实现类的构造方法提供实例。(因为被注解构造方法的子类可能有多个,要从中选其一)
interface MyInterface {
    fun print()
}

class MyInterfaceImpl @Inject constructor() : MyInterface {
    override fun print() {
        Log.i(">>>", "接口类型完成注入")
    }
}

@Module
@InstallIn(ActivityComponent::class)
abstract class InterfaceModule {
    @Binds
    abstract fun bindMyInterface(
        myInterfaceImpl: MyInterfaceImpl
    ): MyInterface
}

这里有3个新出现的注解:
@Module 告诉Hilt从这里获取实例对象
@InstallIn 管理可现范围
@Binds 绑定接口与某个自有子类,可以用@Inject注解构造方法。

在Activiy中的调用和之前一样,直接用@Inject注解变量:

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject lateinit var myInterface: MyInterface

    override fun onCreate(savedInstanceState: Bundle?) {
		...
        myInterface.print()
    }
}
  • 非自己写的类,我们无法注解其构造方法,这种情况下,我们无法绑定接口与其子类,也就是不再使用@Binds,而是直接提供其对象,使用@provides注解方法,类名/方法名没有要求,通俗易懂就好:
@Module
@InstallIn(ActivityComponent::class)
object DependOnYouModule {
    @Provides
    fun providesAInstance(): Retrofit {
    	...
        return retrofitInstance
    }
}

小结一下:

不管怎么写,其实就是要让Hilt知道怎样提供一个被注解后所需要的实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值