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

see here


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