У меня есть приложение для одного действия, и к нему прикреплен SharedViewModel
, его основная цель — использовать для внутренней связи между фрагментами и т. д. Я также использую Область в качестве решения для хранения. Эта модель представления, как и другие модели представления, расширяет модель 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
зависит от жизненного цикла жизненного цикла активности, метод onCleared()
этой модели представления будет вызываться не после onDestroy
вызова активности, а по завершении активности. Это не одно и то же. В результате, когда я выхожу из своего приложения, одно соединение Realm остается открытым, потому что активность не находится в состоянии Законченный. Все другие модели просмотра, связанные из фрагментов, вызвали свои собственные методы onCleared()
, и их соединения Realm закрыты.
Каков наилучший и самый чистый способ справиться с этим?
У меня есть обходной путь, в котором я вручную вызываю viewModel onCleared()
в onDestroy
методе активности, и он работает, но это решение — ерунда.
Заранее спасибо!
Вы должны разделить живые данные на несколько фрагментов, используя общий ViewModel
, но для ваших подключений Realm (Объекты, связанные с миром) я бы рекомендовал использовать ViewModel
, который прикреплен к каждому фрагменту отдельно.
@JeelVankhede, вы правы, но в этой модели SharedViewModel также есть некоторые живые данные, которые использует активность, а также другие фрагменты.
На самом деле @EpicPandaForce был прав, ошибка была в создании ViewModel. Я использовал Кинжал 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
, предоставленные этой фабрикой, не были привязаны к жизненному циклу какой-либо активности и фрагмента. Когда я изменил создание ViewModel как:
sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
после OnDestroy()
активности onCleared()
позвонят.
Спасибо, парни!
when I leave my app, one Realm connection stays open, because activity is not in the Finished state.
это ошибка в вашем коде, учитывая, чтоonCleared()
вызывается, когда вы выходите из приложения (завершаете действие).