【问题标题】:Can not close Realm instance in ViewModel connected with Activity无法在与 Activity 连接的 ViewModel 中关闭 Realm 实例
【发布时间】:2019-04-10 13:20:10
【问题描述】:

我有single activity app,我附上了SharedViewModel,它的主要用途是用于fragment之间的内部通信等。我也使用Realm 作为存储解决方案。此 viewModel 以及其他 viewModel 扩展了 BaseViewModel。

open class BaseViewModel(): ViewModel() {

    val  realm: Realm = Realm.getDefaultInstance()

    override fun onCleared() {
        super.onCleared()
        realm.close()
        Log.d("BVM", "realm is ${ if (realm.isClosed) "closed." else "not closed.  Opened connections: ${Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()!!)}"}")
    }
}

这张图大家都熟悉

由于SharedViewModel的lyfecycle依赖于activity生命周期的生命周期,这个viewModel的onCleared()方法不会在onDestroyactivity调用之后调用,而是在activity结束时调用。这不是一回事。结果,当我离开我的应用程序时,一个 Realm 连接保持打开状态,因为活动未处于 Finished 状态。从片段连接的所有其他视图模型都调用了它们自己的 onCleared() 方法,并且它们的 Realm 连接已关闭。

处理此问题的最佳和最干净的方法是什么?

我有一个解决方法,我在 onDestroy 活动方法中手动调用 viewModel 的 onCleared() 并且它正在工作,但该解决方案是垃圾。

提前致谢!

【问题讨论】:

  • when I leave my app, one Realm connection stays open, because activity is not in the Finished state. 这是您代码中的一个错误,考虑到在您离开应用程序(完成 Activity)时会调用 onCleared()
  • 您应该使用共享的ViewModel 在多个片段之间共享实时数据,但对于您的领域连接(领域相关对象),我建议使用单独附加到每个片段的ViewModel
  • @JeelVankhede,你是对的,但是这个 SharedViewModel 也有一些活动使用的实时数据以及其他片段。

标签: android kotlin realm viewmodel


【解决方案1】:

事实上,@EpicPandaForce 是对的,错误是在 ViewModel 的创建中。我使用 Dagger 2 注入 ViewModelFactory,如下所示:

@Singleton
class ViewModelFactory @Inject constructor(
        private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val creator = creators[modelClass] ?: creators.entries.firstOrNull {
            modelClass.isAssignableFrom(it.key)
        }?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
        try {
            @Suppress("UNCHECKED_CAST")
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }
}

该工厂提供的ViewModels 未绑定到任何活动和片段的生命周期。当我将 ViewModel 的创建更改为:

sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)

OnDestroy() 活动之后,onCleared() 被调用。

谢谢各位!

【讨论】:

    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2018-06-06
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    相关资源
    最近更新 更多