I use "by viewModels" kotlin delegate for get some view model:
val viewModelFactory: ViewModelFactory by lazy { ViewModelFactory.getInstance(this) }
val mainViewModel: MainViewModel by viewModels { viewModelFactory }
ViewModelFactory:
class ViewModelFactory private constructor(activity: AppCompatActivity) : AbstractSavedStateViewModelFactory(activity, null) {
private val application = activity.application
// DataSource
private val appDataSource: AppDataSourceImpl by lazy { AppDataSourceImpl(application) }
// Intercator
private val appDataInteractor: AppDataInteractor by lazy {
AppDataInteractor(appDataSource, userDataSource)
}
companion object {
private var instance: ViewModelFactory? = null
fun getInstance(activity: AppCompatActivity): ViewModelFactory {
return instance ?: ViewModelFactory(activity).also {
instance = it
}
}
}
override fun <T : ViewModel> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
return when {
MainViewModel::class.java.isAssignableFrom(modelClass) -> {
modelClass.getConstructor(AppDataInteractor::class.java, SavedStateHandle::class.java)
.newInstance(appDataInteractor, handle)
}
else -> throw Exception("Unknown ViewModel $modelClass")
}
}
}
When app was closed by backpressed and launched again, it throws exception "java.lang.IllegalArgumentException: SavedStateProvider with the given key is already registered."
I see two solutions to resolve the problem. First is use exitProcess() instead of super.onBackPressed(). It is worked.
override fun onBackPressed() {
if (drawerLayout.isOpen) drawerLayout.close()
else {
if (navController.currentDestination?.id == R.id.nav_homeFragment) {
exitProcess(1) //super.onBackPressed()
}
else navController.navigateUp()
}
}
Second is transfer my viewmodel from activity to application. In the case there are survive after destroying activity. But i can`t use "by viewModels" kotlin delegate in application. I think it is not right solution (but it work too).
Where is the right way to get viewmodels?