我可以管理生命周期所有者,用 Koin 注入 viewModel 吗?

Posted

技术标签:

【中文标题】我可以管理生命周期所有者,用 Koin 注入 viewModel 吗?【英文标题】:Can I manage lifecycle owner, injecting viewModel with Koin? 【发布时间】:2019-05-22 22:49:02 【问题描述】:

我有一个 Activity 应用程序。

我想将 viewModel 绑定到父片段生命周期(FlowFragmentLogin),并与子片段(CellFragmentInfoFragmentetc)共享。这样当我从 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 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Blazor、对象生命周期和依赖注入

详解.NET Core 依赖注入生命周期

quarkus依赖注入之七:生命周期回调

quarkus依赖注入之七:生命周期回调

如何在 Room MVVM 架构中实现 Koin 依赖注入

使用 koin 作为 Android 注入工具,真香