我可以管理生命周期所有者,用 Koin 注入 viewModel 吗?
Posted
技术标签:
【中文标题】我可以管理生命周期所有者,用 Koin 注入 viewModel 吗?【英文标题】:Can I manage lifecycle owner, injecting viewModel with Koin? 【发布时间】:2019-05-22 22:49:02 【问题描述】:我有一个 Activity 应用程序。
我想将 viewModel 绑定到父片段生命周期(FlowFragmentLogin
),并与子片段(CellFragment
、InfoFragment
、etc
)共享。这样当我从 FlowFragmentLogin
移动到 FlowFragmentMain
时,就会调用 viewModel onCleared()
。
但我发现的唯一方法是在 Activity 之间共享 viewModel,它是 Fragments: https://insert-koin.io/docs/1.0/documentation/koin-android/index.html
并且无法控制生命周期所有者。这对我来说是不可接受的,至少因为这个 viewModel 将一直存在到应用程序死亡。
【问题讨论】:
显然你可以指定 ViewModelStore,或者至少我听说过。 在Activity中发起一个ViewModel怎么样,fragment也有自己的ViewModel,我们可以让ViewModel互相对话。你说什么? 【参考方案1】:在 Koin 版本3.1.3
中有一个新的扩展函数koinNavGraphViewModel
。
只需添加以下依赖项
implementation "io.insert-koin:koin-androidx-navigation:$koin_version"
可以这样使用
private val viewModel: MyViewModel by koinNavGraphViewModel(R.id.my_graph)
【讨论】:
【参考方案2】:您可以通过使用新版本的 Koin(2.1.0) 和一些魔法来做到这一点 :)
你只需要添加这个扩展功能:
inline fun <reified VM : ViewModel> Fragment.sharedGraphViewModel(
@IdRes navGraphId: Int,
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
) = lazy
val store = findNavController().getViewModelStoreOwner(navGraphId).viewModelStore
getKoin().getViewModel(ViewModelParameter(VM::class, qualifier, parameters, null, store, null))
现在您可以通过以下方式从嵌套图中简单地获取 ViewModel:
private val viewModel: MyViewModel by sharedGraphViewModel(R.id.my_graph)
【讨论】:
【参考方案3】:自导航2.1.0-alpha02
:
您现在可以通过 Kotlin 用户的 by navGraphViewModels() 属性委托或使用添加到 NavController 的 getViewModelStore() API 创建在导航图级别范围内的 ViewModel。
您可以找到更改日志here 和document。
很遗憾 Koin 无法支持该功能,因为 viewModel()
或 sharedViewModel()
已绑定到 Activity。但是2.1.x
已经计划支持nav,你可以追踪here。
现在这是我的解决方案:
-
在 Koin 中使用
navGraphViewModels()
而不是 viewModel()
。
class DetailFr : Fragment()
private val vm: DetailViewModel by navGraphViewModels(R.id.main_nav_graph)
-
让 ViwModel 实现
KoinComponent
,这样我们就可以使用 by inject()
而不是构造函数注入。
class DetailViewModel : ViewModel(), KoinComponent
private val repo: DetailRepository by inject()
// othetr objects you need
希望这会有所帮助
【讨论】:
以上是关于我可以管理生命周期所有者,用 Koin 注入 viewModel 吗?的主要内容,如果未能解决你的问题,请参考以下文章