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
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。