How to share same instance of ViewModel between Activities using Koin DI?
I would suggest making the app a ViewModelStoreOwner
and injecting the viewModels using as owner the app.
The code required would look like this
class App : Application(), ViewModelStoreOwner {
private val mViewModelStore = ViewModelStore()
override fun getViewModelStore(): ViewModelStore {
return mViewModelStore
}
}
You can define some extensions to easily inject the viewModels
val Context.app: App
get() = applicationContext as App
inline fun <reified T : ViewModel> Context.appViewModel(
qualifier: Qualifier? = null,
noinline state: BundleDefinition? = null,
noinline parameters: ParametersDefinition? = null
): Lazy<T> {
return lazy(LazyThreadSafetyMode.NONE) {
GlobalContext.get().getViewModel(qualifier, state, { ViewModelOwner.from(app, null) }, T::class, parameters)
}
}
inline fun <reified T : ViewModel> Fragment.appViewModel(
qualifier: Qualifier? = null,
noinline state: BundleDefinition? = null,
noinline parameters: ParametersDefinition? = null
): Lazy<T> {
return lazy(LazyThreadSafetyMode.NONE) {
GlobalContext.get().getViewModel(qualifier, state, { ViewModelOwner.from(requireContext().app, null) }, T::class, parameters)
}
}
You can then inject your viewModel like this
class MainActivity : AppCompatActivity() {
private val mAppViewModel: AppViewModel by appViewModel()
}
The advantage of this solution is that you don't need to recreate the view model and if you decide to save the state between app restarts, you can easily make the app an SavedStateRegistryOwner
as well and using the SavedStateHandle
save/restore your state from inside the viewModel, being now bound to the process lifecycle.
you must use single{}
instead of viewModel{}
in module declaration.
single { SharedViewModel() }
And, you can use viewModel() in your views.
View1
private val viewModel: SharedViewModel by viewModel()
View2
private val viewModel: SharedViewModel by viewModel()
But you must load modules when view start by
loadKoinModules(module1)
The important point is that you must unload module in when destroy view.
unloadKoinModules(mainModule)
So, when unload modules your singleton ViewModel will be destroyed.
#EDIT
Now, you can use sharedViewModel declaration.
After some research or discussion on architecture level and also report and issue github Koin,i found solution for this In this scenario,We should save that state/data into Repository which we need to share between multiple activities not in the viewModel and two or more different ViewModels can access same state/data that are saved in single instance of repository
you need to read more about ViewModel
to understand it better.
https://developer.android.com/topic/libraries/architecture/viewmodel
ViewModel
is connected to your Activity
so you can share your Activities ViewModel
only between his Fragments
,
that is what mean sharedViewModel
in koin
sharedViewModel
is the same if you use ViewModel Factory
with same context
.
sharing any data between Activities
can be done via Intent
, there is no another way in Android,
or you can keep some static / global
data and share it between Activities