注册

Android App封装 —— DI框架 Hilt?Koin?

背景


前面的项目Github wanandroid例子我们可以看到,我们创建Repository和ViewModel的时候,都是直接创建的


class MainViewModel : BaseViewModel<MainState, MainIntent>() {
private val mWanRepo = HomeRepository()
...
}


class MainActivity : BaseActivity<ActivityMainBinding>() {

override fun onCreate(savedInstanceState: Bundle?) {
mViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
}

但是一般一个repository会被多个viewModel使用,我们不想创建多个同样类型的repository实例,这时候我们需要将WanRepository设置为单例。但是当代码越来越多,对象的共享依赖关系以及生命周期越来越复杂的时候,我们全部自己手写显然是比较复杂的。


所以Goolge强推我们使用DI(Dependency Injection)依赖注入来管理对象的创建,之前推出了强大的Dagger,但是由于难学难用,很少有人用到这个框架。后面又推出了Hilt,基于Dagger实现,针对于Android平台简化了使用方式,原理和Dagger是一致的。


本来准备将Hilt引用到项目中,后来发现了一个轻量级的DI框架koin,两者学习对比了一下之后还是决定使用Koin这个轻量级的框架,koin和Hilt的详细对比就不在此展开了,网上有很多文章。


那么就开始动工,准备在项目中集成koin吧。


koin


koin官网,官网永远是学习一个东西的最佳途径


1. 依赖


网上看到很多koin的使用案例,我看依赖的都是2.X的包


implementation "org.koin:koin-android:$koin_version"
implementation "org.koin:koin-android-viewmodel:$koin_version"

后面我去官网看了下文档,发现koin已经升级到3.x了,合并所有 Scope/Fragment/ViewModel API,只需要引用一个包就可以了


    implementation "io.insert-koin:koin-android:$koin_version" //3.3.1

2. 启动


添加好依赖后,可以在Application中启动koin,初始化koin的配置,代码如下


class App : Application() {
override fun onCreate() {
super.onCreate()

startKoin {
//开始启动koin
androidLogger()
androidContext(this@App)//这边传Application对象,这样你注入的类中,需要app对象的时候,可以直接使用
modules(appModule)//这里面传各种被注入的模块对象,支持多模块注入
}
}
}

3. 模块Module


上文中的modules(appModule),是用来配置koin使用的Module有哪些,那么Module是什么呢?


Koin是以Module的形式组织依赖项,我们可以将可能用到的依赖项定义在Module中,也就是对象的提供者


val repoModule = module {
single { HomeRepository() }
}

val viewModelModule = module {
viewModel { MainViewModel(get()) }
}

val appModule = listOf(viewModelModule, repoModule)

上面这段代码就是定义了两个Module,一个我专门用来定义repository,一个专门用来定义viewModel。


然后通过get()inject(),表示在需要注入依赖项,也就是对象的使用者,这时就会在Module里面检索对应的类型,然后自动注入。


所以之前Repository的创建变为


val mWanRepo: HomeRepository by inject(HomeRepository::class.java)

并且依据single定义为了单例


进一步简化可以将repository写到ViewModel的构造方法中


class MainViewModel(private val homeRepo: HomeRepository) : BaseViewModel<MainState, MainIntent>() {
...
}

根据viewModel { MainViewModel(get()) }的定义,在构造MainViewModel的时候会自动因为get()填充HomeRepository对象


4. Activity中使用ViewModel


class MainActivity : BaseActivity<ActivityMainBinding>() {

private val mViewModel by viewModel<MainViewModel>()

}

总结


koin和Hilt,大家可以看自己的习惯使用,Hilt的特点主要是利用注解生成代码,使用方便,效率也挺高的。koin我主要是看中它比较轻量级,可以快速入门使用。


项目地址:Github wanandroid


作者:剑冲
链接:https://juejin.cn/post/7179151577864175671
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册