Reputation: 2221
I have single activity app and I have SharedViewModel
attached to it, its main purpose is to be used for inner communication between fragments, etc. I also use Realm as storage solution. This viewModel as well as the others viewModels extends 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()!!)}"}")
}
}
We are all familiar with this picture
Since SharedViewModel
's lyfecycle depends on lifecycle of activity's lifecycle, onCleared()
method of this viewModel will be called not after onDestroy
call of activity, but when activity is finished. It is not the same thing. As a result of that, when I leave my app, one Realm connection stays open, because activity is not in the Finished state. All other viewmodels connected from fragments had called their own onCleared()
methods and their Realm's connections are closed.
What is the best and cleanest way to handle this?
I have a workaround in which I call viewModel's onCleared()
manually in onDestroy
method of activity and it's working, but that solution is rubbish.
Thanks in advance!
Upvotes: 2
Views: 227
Reputation: 2221
As a matter of fact, @EpicPandaForce was right, the bug was in ViewModel's creation. I used Dagger 2 for injection of ViewModelFactory
which looks like this:
@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)
}
}
}
and ViewModel
s provided by this factory were not bound to lifecycle of any activity and fragment. When I changed the creation of ViewModel as:
sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
after OnDestroy()
of activity, onCleared()
get called.
Thanks, guys!
Upvotes: 1