吞噬
从Google团队中提出了一个名为Hilt的新依赖注入库。它是在匕首库的顶部设计的,并提供了更简单,更少的样板API,以处理Android应用程序中的依赖项。第一次尝试,这是一个真正的改变游戏规则的人。因此,我们将简要介绍一下,然后讨论一些观点。
为什么要建造?
首先,匕首很难开始,尤其是对于初学者而言。其次,随着匕首的贬低,在Android中解决了一个新图书馆。它也比匕首少,使测试更简单。
匕首的问题 - android
长话短说,Android很难,@ContributesAndroidInjector
使事情变得更加困难。以我本人的看法,这是一个有力的理由,要放弃匕首。忘记在那里添加依赖关系,并试图解决构建问题,给尝试使用它带来很多头痛。
是什么用刀柄改变了游戏?
如果我尝试用它来表达它,我会说它像应将其对待的Android类一样对待,正常类。在匕首,活动,碎片,工人是课堂上,但也是神秘的物体,与之合作。
非常可怕。这篇文章假设读者知道匕首
快速开始使用
让我们从模块开始。由于它是在匕首顶部建造的,因此还有一些东西。让我们假设我们有一个例子:
@Module
object MyAppScopeDependenciesModule{
@Provides
@Singleton
fun provideDependency1() : Dep1 = Dep1.builder().build()
@Provides
@Singleton
fun provideDependency2() : Dep2 = Dep2.builder().build()
}
,让我们仅出于示例(应用程序级别范围)而创建一个组件:
@Singleton
@Component(modules = [MyAppScopeDependenciesModule::class])
interface MyApplicationComponent{
val dependency1: Dep1
val dependency2: Dep2
@Component.Factory
interface Factory{
fun create(application: Application): MyApplicationComponent
}
}
让我们点击构建按钮,然后开始导入依赖项:
class MyApplication : Application(){
@Inject lateinit var dep1: Dep1
override fun onCreate(){
super.onCreate()
DaggerMyApplicationComponent.factory().create(this)
}
}
范围和模块之间的关系总是神秘的,他们从不关心检查匕首的注释处理器产生的内容。因此,我必须说,这是那些建造剑柄的人发现的。在匕首中,范围的模块与范围内的分量相连,如果这两个(或更多模块)相关。
,它提供了近0个信息。现在,让我们尝试用刀柄构建上述示例:
@Module
@InstallIn(ApplicationComponent::class)
object MyAppScopeDependenciesModule{
@Provides
fun provideDependency1() : Dep1 = Dep1.builder().build()
@Provides
fun provideDependency2() : Dep2 = Dep2.builder().build()
}
按下构建按钮之前,这就是您所需要的。
我的组件在哪里?
Hilt为您提供组件。无需创建组件或范围。考虑组件和范围合并在一起的组件和范围。实际上,这就是为什么HILT是游戏规则改变者的原因。 Hereis组件层次结构需要用于来自dagger.hilt.android.components.*
的Android应用程序。基本上,您知道您的依赖性寿命,现在您知道要在哪里安装它。最后一步,让我们执行依赖注入:
@HiltAndroidApp
class MyApplication : Application(){
@Inject lateinit var dep1: Dep1
override fun onCreate(){
super.onCreate()
...
}
}
另外,如果您想在活动,碎片,视图,服务或广播接收器中执行DI,那么AndroidInjection.inject(this)
不再需要。相反,只需用@AndroidEntryPoint
标记班级的顶部:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
// either comming from an ActivityComponent or ApplicationComponent
@Inject lateinit var dependency: Dependency
override fun onCreate() {
super.onCreate()
...
}
}
注射发生在
中onCreate()
那是最好的吗?
nope,Hilt最终也解决了ViewModel
s实例化过程的问题,通常,运行时并立即在构造函数中构建时间依赖关系。在使用之前,我曾经安装AssistedInject以正确地创建saveStateHandle
,并且有一个关于如何做到这一点的full tutorial。但是,让我们做一些简单的简短演示:
class MyViewModel @AssistedInject constructor(
private val dep1: Dep1,
@Assisted private val saveStateHandle: SaveStateHandle
){
@AssistedInject.Factory
interface Factory{
fun create(saveStateHandle: SaveStateHandle) : MyViewModel
}
}
然后为其安装一个模块:
@AssistedModule
@Module(includes = [AssistedInject_ViewModelModule::class])
abstract class ViewModelModule
然后在AppComponent
中露出视图模型:
@Component(...)
interface AppComponent{
...
val vmFactory: MyViewModel.Factory
...
}
之后,我可以在我的片段中快乐地拥有一个观点:
inline fun Fragment.viewModelFactory(
crossinline provider: (SavedStateHandle) -> T
) = viewModels {
object : AbstractSavedStateViewModelFactory(this, fragment.arguments ?: Bundle()) {
override fun create(key: String, modelClass: Class, handle: SavedStateHandle): T =
provider(handle) as T
}
}
class HomeFragment : Fragment() {
private val myViewModel by viewModelFactory { Application.component().vmFactory.create(it) }
...
}
有关此解决方案的更多详细信息,请检查上面提供的链接。
必须只为ViewModel做所有这些步骤很痛苦,更不用说AssistedInject
还有很多事情要做(或者我可以使用Koin,但这不是目前的话题)。
使用刀柄,这很简单:
class EditorViewModel @ViewModelInject constructor(
private val playgroundRepository: PlaygroundRepository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {}
之后,不需要别的。只需像往常一样导入ViewModel:
//inside Fragment
private val editorViewModel by viewModels()
请检查Hilt的文档以获取正确的依赖项。
ViewModel
和WorkManager
解决方案作为分开的依赖项出现。有关更多信息,请检查here
Ondestroyview
就个人而言,我将使用刀柄作为Android的依赖性注入工具,这将是一个非常高兴的开发人员。与匕首相比,它使跟踪依赖性易于跟踪,易于启动和更少的样板。
但是,我在使用刀柄时注意到的一个缺点是,它在项目上增加了更多的抽象,您要么需要更多地了解代码生成,要么更好地不使用它。另外,忘记执行di为AndroidInjection.inject(this)
或DaggerMComponent.builder().build().inject(this)
并用@AndroidEntryPoint
is注释课程仍然很棘手,无论哪种方式,您都会忘记。但是,这没有问题,因为该错误将在构建时间产生。
尽管如此,它看起来很有希望。
ondestroy
我希望我简要介绍一下,以开始使用刀柄,还对此发表了一些意见。 Android并不是一个简单的框架/库,可以使用的每个工具越来越多地配置,这始终是一个巨大的头痛。因此,我很高兴Google团队引入了Hilt。对于这里的所有匕首粉丝来说,Hilt是对所有抱怨匕首复杂性的人的强烈论点。
Stavro Xhardha