使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(四)

简介: 使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(四)

辅助注入


如果通过看前面的文章学会了Hilt的基础使用,那么恭喜你,你基本已经可以在项目中展开使用Hilt框架为你的项目提供自动注入功能了,但是有一些场景你可能会感到疑惑,回顾之前的注入,你会发现一个问题:当使用Hilt构建一个对象的时候,在定义对象的时候,就要求所有参数已经被确定,但是实际场景中,我们有许多参数是无法在定义对象的阶段就被确定的,一些参数需要在项目运行时才能被确定,例如网络请求的结果等,这些动态的参数让我们无法使用Hilt为我们注入,至少目前还不行。

为了解决这些动态参数导致的问题,dagger2(即Hilt的底层框架)提供了一种解决问题的方案:辅助注入

辅助注入是一种依赖注入 (DI) 模式,用于构造一个对象,其中一些参数可能由 DI 框架提供,而其他参数必须在创建时由用户传入(也称为“辅助”)。 工厂通常负责组合所有参数并创建对象。

依然是废话不多说环节,我们使用具体的案例来讲解如何使用辅助注入


data class Wheel(
    val name:String
)
data class Engine(
    val name:String
)
class Car(
    val wheel:Wheel,
    val engine:Engine,
    val number:Int
)

假设我们有轮子、引擎和汽车三个实体类,其中汽车是由轮子和引擎组成的,我们希望创建一个工厂,自动为我们生成某个类型的汽车,因此轮子和引擎的构建方式是固定的,但是汽车的编号每个汽车是不同的。

按照之前的文档,我们编写Module类,但是我们会发现,我们无法在定义provides方法阶段就定义好number。


@InstallIn(SingletonComponent::class)
@Module
object JiLiCarModule{
    @Singleton
    @Provides
    fun provideJiLiWheel():Wheel{
        return Wheel("吉利牌车轮")
    }
    @Singleton
    @Provides
    fun provideJiLiEngine():Engine{
        return Engine("吉利牌引擎")
    }
    @Provides
    fun provideJiLiCar(
        wheel: Wheel,
        engine: Engine
    ):Car{
        return Car(
            wheel = wheel,
            engine = engine,
            //👇🏻出问题的部分,我们无法明确这个编号
            number = ???
        )
    }
}

也许某些情况下,我们确实能在定义provides方法的时候就明确number的生成方式(例如随机数的业务场景),但是我们要讨论的是在定义provides方法阶段无法明确参数的情况,因此我们需要dagger提供的辅助注入来帮助我们完成这种场景下的Hilt注入。


动手实战


一、为汽车实体类添加@AssistedInject注解,同时为动态传入的参数添加@Assisted注解,这里是number。


class Car @AssistedInject constructor(
    val wheel:Wheel,
    val engine:Engine,
    @Assisted
    val number:Int
)

二、构建工厂类,使用@AssistedFactory注解表示这是一个辅助注入工厂类,同时编写需要注入的实体类的构建方法,方法只需要动态传入的参数,在这里指的是number


@AssistedFactory
interface JiLiCarFactory{
    fun createJiLiCar(
        number:Int
    ):Car
}

三、注入工厂类,这里和之前直接注入对象使用方法基本是一致的,区别只有一个,这里注入的是工厂


@AndroidEntryPoint
class YouFragment : Fragment() {
    //注入工厂类
    @Inject
    private lateinit var jiLiCarFactory: JiLiCarFactory
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //使用工厂类,传入动态参数构建具体的对象
        val jiLiCar: Car =jiLiCarFactory.createJiLiCar(114514)
    }
}

四、解决相同类型参数注入问题

当你有多个相同类型的参数的时候,Hilt会不知道如何注入,例如我们的实体类是这样的情况:


class Car @AssistedInject constructor(
    val wheel:Wheel,
    val engine:Engine,
    @Assisted
    val number:Int,
    @Assisted
    val number2:Int
)

这里出现了两个相同类型(Int)的参数,因此我们需要区分开来,这里使用注解@Assisted的参数来区分,改造为如下:


class Car @AssistedInject constructor(
    val wheel:Wheel,
    val engine:Engine,
    @Assisted("number")
    val number:Int,
    @Assisted("number2")
    val number2:Int
)

同时别忘了为工厂的方法也添加对应的注解,否则Hilt一样无法知道如何映射对应的参数


@AssistedFactory
interface JiLiCarFactory{
    fun createJiLiCar(
        @Assisted("number") number:Int,
        @Assisted("number2") number2:Int
    ):Car
}
工厂类用法和原
来的保持一致,只是多加了参数


val jiLiCar=jiLiCarFactory.createJiLiCar(114514,1111)


总结


好的,关于Hilt的系列就到此结束了,笔者写这系列的初衷是帮助那些刚刚使用Hilt的新手快速入门并动手使用Hilt,并没有做太深入的分析(笔者的程度也没有到那个层次,就不班门弄斧了),同时也为很久没有更新文章抱歉,近期会恢复更新频率,同时也会谈谈compose相关的话题,敬请期待。


相关文章
|
3月前
|
XML API Android开发
【Android 从入门到出门】第三章:使用Hilt处理Jetpack Compose UI状态
【Android 从入门到出门】第三章:使用Hilt处理Jetpack Compose UI状态
69 4
|
Java 数据库 Android开发
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(三)
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(三)
150 0
|
Android开发 容器
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(二)下
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(二)
86 0
|
Android开发 容器
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(二)上
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(二)
100 0
|
Android开发 容器
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(一)下
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(一)
128 0
|
程序员 Android开发 容器
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(一)上
使用Hilt完成依赖注入,让你的安卓代码层次有几层楼那么高(一)
78 0
|
缓存 API 调度
Android OkHttp+Retrofit+Rxjava+Hilt实现网络请求框架
🔥 介绍 本文通过OkHttp+Retrofit+Rxjava+Hilt实现一个网络请求框。
714 0
Android OkHttp+Retrofit+Rxjava+Hilt实现网络请求框架
|
测试技术 数据库 Android开发
Android Jetpack 浅析Hilt依赖注入
首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部方法获取对象实例的称为依赖注入;而依赖注入又可以简单分为`手动注入`和`自动注入`两种方式;`Hilt`就是基于Dagger进行`场景化优化`的一个依赖注入库,Hilt是Google专门为Android平台打造的一个依赖注入库,在使用上极大程度进行啦简化(与dagger相比)
379 1
Android | 依赖注入与 Dagger2 框架【@Deprecated】
Android | 依赖注入与 Dagger2 框架【@Deprecated】
193 0
Android | 依赖注入与 Dagger2 框架【@Deprecated】