Reputation: 539
Difference between ActivityViewModels and lazy ViewModelProvider?
I've seen 2 ways to initialize a viewmodel:
private val someViewModel: SomeViewModel by activityViewModels()
private val someOtherViewModel: SomeOtherViewModel by lazy {
ViewModelProvider(this).get(SomeOtherViewModel::class.java)
}
I know lazy
initializes the ViewModel only when it's needed and that activityViewModels
is useful for sharing data between fragments, but other than that what's the difference?
Android documentation says the activityViewModels
is scoped to the activity, but does that mean if the same viewmodel is used in multiple fragments within the same activity using activityViewModels
that there's only one instance created that's shared between all the fragments?
Upvotes: 22
Views: 24636
Reputation: 137
use by activityViewModels() when you have 1-shared code in ViewModel used by many fragments 2-these fragments had the same parent Activity.
-So if you don't have this scenario use normal viewModel Code Ex :- private lateinit var viewModel: YourViewModelClass viewModel = ViewModelProvider(this)[YourViewModelClass ::class.java]
Upvotes: 0
Reputation: 455
A current version of this is replace
private val viewModel by lazy { ViewModelProvider(this)[TaskTimerViewModel::class.java] }
with
private val viewModel: TaskTimerViewModel by activityViewModels()
The former just differs the initialization but creates a viewModel instance for each Fragment. This works but creates more work, the query to get the data is run for each Fragment.
The latter gets the ViewModel that scopes to the activity. It will get the same view model for multiple Fragments that are in the same activity.
TaskTimerViewModel was created with
class TaskTimerViewModel(application: Application) : AndroidViewModel(application) {
But the fact that it used AndroidViewModel did not seem to cause a problem.
Thanks for the previous answer, it was spot on when it was created and very clear. Hopefully this update is of some use to someone.
Upvotes: 0
Reputation: 1735
When you call ViewModelProvider(this)
, this
refers to the ViewModelStoreOwner
.
For each unique ViewModelStoreOwner, there will be a unique ViewModel of the given type
.
Now coming to the question.
When you call
private val someOtherViewModel: SomeOtherViewModel by lazy {
ViewModelProvider(this).get(SomeOtherViewModel::class.java)
}
you are getting a ViewModel that is scoped to the current Fragment/Activity. Lazy
just defers the initialization.
When you call
private val someViewModel: SomeViewModel by activityViewModels()
you are getting a ViewModel that is scoped to the Activity. When multiple fragments use the same code, they are requesting ViewModels scoped to the parent Activity. If the parent Activity for all the Fragments is the same, the Fragments will get the same ViewModel since the ViewModelStoreOwner
connected to the Activity remains the same.
Upvotes: 40