Reputation: 492
I am using Koin
library in Kotlin for DI
Koin providing by viewmodel()
for get instance of ViewModel by sharedViewModel()
to get same instance in fragments.
How can I get same instance of the ViewModel in activities ? I didn't find any way to achieve this.
Upvotes: 19
Views: 23263
Reputation: 41
I know this is very very late but you can try this:
if you are extending a baseviewmodel, you need to declare the baseViewmodel as a single
then in your respective activity inject the BaseViewModel.
Practical example:
val dataModule = module {
single { BaseViewModel(get(), get()) }
}
in your ViewModel
class LoginViewModel(private val param: Repository,
param1: Pref,
param2: Engine) : BaseViewModel(param1, param2)
Then in your activity class
val baseViewModel: BaseViewModel by inject()
Hope this help someone.
Upvotes: -2
Reputation: 159
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.
Upvotes: 4
Reputation: 492
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
Upvotes: 7
Reputation: 2150
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
Upvotes: 2