我正在参与「启航计划」
上一篇文章的方便进口:写文章 – 运用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相关的话题,敬请期待。