Reputation: 159
I have one view model which should be shared between two fragments. The two fragments are in a nav graph and in each fragment I do this to reference the view model:
private val viewModel: MyViewModel by navGraphViewModels(R.id.my_nav_graph)
As I understand, this will keep the lifecycle of the view model with the nav graph, and it's all working great. The two fragments share data from the view model.
But I noticed that when I switch from the first fragment to the second, the init method in the view model is running again and if I print out the name of the viewmodel, I get one instance when the first fragment loads and another name when the second one loads (similar to this format MyViewModel@e7e7690).
Now, the view model works fine for the two fragments, the data is shared and all, but I'm concerned that there might be another view model lingering in the background which will not be removed correctly. In the project the view model is subscribing to a service on creation and unsubscribing onDestroyed(), but onDestroyed() is only called once when the fragments are destroyed, meaning that one of the subscribers are still registered, hence it's a problem if the view model are created twice and not handled properly.
Upvotes: 1
Views: 616
Reputation: 346
I am not familiar with the way you are instantiating your view model, but I wanted to share the way I instantiate mine, as I commonly use the nav graph approach to ensure I have a single instance tied to the lifecycle of the nav graph. The following code would occur within a method of a fragment in order to instantiate the view model:
val myNavController: NavController = NavHostFragment.findNavController(this) // "this" is your fragment
val myViewModelStoreOwner: ViewModelStoreOwner = myNavController.getViewModelStoreOwner(R.id.my_nav_graph)
val myViewModelProvider = ViewModelProvider(myViewModelStoreOwner) // If you use a ViewModelFactory, you can pass it here as the second parameter.
val myViewModel: MyViewModel = myViewModelProvider.get(MyViewModel::class.java)
This will ensure that a single view model is instantiated if none already exists for a fragment on the given nav graph. If one does, it will retrieve that one. Once there are no more fragments tied to the nav graph existing within your stack, the view model will be destroyed.
Upvotes: 1