我有单个活动应用程序,我附加了SharedViewModel
,其主要目的是用于片段之间的内部通信等。我还使用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取决于活动生命周期的生命周期,因此不会在onCleared()
调用活动之后调用此viewModel的onDestroy
方法,但是当活动完成时。这不是一回事。因此,当我离开我的应用程序时,一个Realm连接保持打开状态,因为活动未处于“已完成”状态。从片段连接的所有其他视图模型都调用了自己的onCleared()
方法,并且它们的Realm连接已关闭。
处理这个问题的最好和最干净的方法是什么?
我有一个解决方法,我在onCleared()
活动方法中手动调用viewModel的onDestroy
并且它正在工作,但该解决方案是垃圾。
提前致谢!
事实上,@ EpicPandaForce是对的,这个bug出现在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)
}
}
}
这家工厂提供的ViewModel
s并不受任何活动和碎片的生命周期的约束。当我将ViewModel的创建更改为:
sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
在OnDestroy()
活动后,onCleared()
被召唤。
多谢你们!