Koin: How to share same instance of ViewModel between Activities ?

Created on 22 Jul 2019  路  12Comments  路  Source: InsertKoinIO/koin

is there any way to pass custom ViewModel Factory class or any way to share same view model instance between multiple activities ?
i need to share same ViewModel instance between 2 activities and i did not find any way to do it. please provide some suggestion to achieve the same.

question

Most helpful comment

@iamsahilarora I would try this:

val myModule = module { 
  single { MyViewModel(get()) } 
} 

and in your activities:

val myVm: MyViewModel by inject()

This is more of a hack, because it bypasses all the viewModel injection logic and should just inject a singleton.

I think this should give you one instance of your viewmodel shared between two activities, however as this viewModel isn't tied to lifecycle of either activity I think onCleared() method in that viewModel wont be called (it is normally called when lifecycle of ui component that the vm is bound to ends). So if you do some background processing its up to you to cancel it "manually" if you need to.

So at this point your MyViewModel doesnt really have to subclass ViewModelat all.

I also thought about your use case from architectural point of view and, my assumption being you want to share/communicate some state between two activities I would still inject each activity with its own viewModel and then inject each of these viewModels with a repository only through which the state is shared like this:

image

All 12 comments

It works like that by default.

I don't know if it's intentional or not, as per documentation, to have shared vm's you would use val vm by sharedViewModel<MyVm>(). But generally the documentation is very inaccurate.

@curliq don't hesitate to contribute to the documentation. As you may know, we are working on our free time. Feel free to suggest improvements, even for the documentation which is already very big to maintain.

I don't know if it's intentional or not, as per documentation, to have shared vm's you would use val vm by sharedViewModel<MyVm>(). But generally the documentation is very inaccurate.

This only works for fragments, not activity.

If you need to share an instance of something between multiple activites, this sounds like a job for single in your module. Because if you think about it - what is above single activity scope ? application scope and you achieve that with "top" scope module with single

or even scope API if you need

@Ejstn I agree to usesinglescope and create singleton viewmodel using ViewModelProvider . how can i achieve this using koin ? can i use single & viewModel scopes together in koin ?

@iamsahilarora I would try this:

val myModule = module { 
  single { MyViewModel(get()) } 
} 

and in your activities:

val myVm: MyViewModel by inject()

This is more of a hack, because it bypasses all the viewModel injection logic and should just inject a singleton.

I think this should give you one instance of your viewmodel shared between two activities, however as this viewModel isn't tied to lifecycle of either activity I think onCleared() method in that viewModel wont be called (it is normally called when lifecycle of ui component that the vm is bound to ends). So if you do some background processing its up to you to cancel it "manually" if you need to.

So at this point your MyViewModel doesnt really have to subclass ViewModelat all.

I also thought about your use case from architectural point of view and, my assumption being you want to share/communicate some state between two activities I would still inject each activity with its own viewModel and then inject each of these viewModels with a repository only through which the state is shared like this:

image

@Ejstn You are Right. Thanks for this suggestion
Using the single instance of repository to share any common state or data between multiple activities is best solution for this rather then sharing Single View-model instance between multiple activities.

Hey @Ejstn, you proposal of architecture looks awesome, I have a question.
In order to save the state for future sharing, is it needed to persist it or could it be mean while repository instance is in memory.
This is because, in my opinion, repository should be stateless.

@jimmyalvarezcalderon stateless repository is probably a good idea. My idea of repository is that its some abstraction over one or more data sources (network, db, disk, etc) - it coordinates/operates on these data sources, but doesnt contain state on its own.

Key thing for saving data/state in memory - it is all lost when application process is killed - so that is up to your use case if thats ok/expected.

@jimmyalvarezcalderon stateless repository is probably a good idea. My idea of repository is that its some abstraction over one or more data sources (network, db, disk, etc) - it coordinates/operates on these data sources, but doesnt contain state on its own.

Key thing for saving data/state in memory - it is all lost when application process is killed - so that is up to your use case if thats ok/expected.

Agree completely and thanks for your advice

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sankarsana picture sankarsana  路  4Comments

Jeevuz picture Jeevuz  路  4Comments

ILAgent picture ILAgent  路  3Comments

hkelidari picture hkelidari  路  3Comments

luna-vulpo picture luna-vulpo  路  4Comments