Introduction
ViewModelProviders.of() was deprecated in AndroidX Lifecycle version 1.1.0 and removed in later versions. The replacement is ViewModelProvider(owner) constructor or the Kotlin by viewModels() delegate. The migration is straightforward — replace ViewModelProviders.of(this).get(MyViewModel::class.java) with ViewModelProvider(this).get(MyViewModel::class.java) or use by viewModels() for the cleanest Kotlin syntax.
The Deprecated Code
1// DEPRECATED — ViewModelProviders.of()
2import androidx.lifecycle.ViewModelProviders
3
4class MyActivity : AppCompatActivity() {
5 override fun onCreate(savedInstanceState: Bundle?) {
6 super.onCreate(savedInstanceState)
7 val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
8 }
9}
10
11// In a Fragment
12class MyFragment : Fragment() {
13 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
14 val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
15 }
16}
Fix 1: ViewModelProvider Constructor (Java & Kotlin)
1// CORRECT — ViewModelProvider(owner)
2import androidx.lifecycle.ViewModelProvider
3
4class MyActivity : AppCompatActivity() {
5 override fun onCreate(savedInstanceState: Bundle?) {
6 super.onCreate(savedInstanceState)
7 val viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
8 }
9}
10
11// In a Fragment
12class MyFragment : Fragment() {
13 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
14 val viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
15 }
16}
Java equivalent:
// Java
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
Fix 2: by viewModels() Delegate (Kotlin — Recommended)
The cleanest approach using Kotlin property delegates:
1// Add dependency: implementation "androidx.activity:activity-ktx:1.8.0"
2// or: implementation "androidx.fragment:fragment-ktx:1.6.0"
3
4class MyActivity : AppCompatActivity() {
5 private val viewModel: MyViewModel by viewModels()
6
7 override fun onCreate(savedInstanceState: Bundle?) {
8 super.onCreate(savedInstanceState)
9 // viewModel is lazily created on first access
10 viewModel.loadData()
11 }
12}
13
14class MyFragment : Fragment() {
15 // Fragment-scoped ViewModel
16 private val viewModel: MyViewModel by viewModels()
17
18 // Activity-scoped ViewModel (shared between fragments)
19 private val sharedViewModel: SharedViewModel by activityViewModels()
20}
With Custom ViewModelFactory
When your ViewModel needs constructor parameters:
1// ViewModel with parameters
2class UserViewModel(private val userId: String) : ViewModel() {
3 // ...
4}
5
6// Custom factory
7class UserViewModelFactory(private val userId: String) : ViewModelProvider.Factory {
8 override fun <T : ViewModel> create(modelClass: Class<T>): T {
9 if (modelClass.isAssignableFrom(UserViewModel::class.java)) {
10 @Suppress("UNCHECKED_CAST")
11 return UserViewModel(userId) as T
12 }
13 throw IllegalArgumentException("Unknown ViewModel class")
14 }
15}
16
17// Usage with ViewModelProvider
18val viewModel = ViewModelProvider(this, UserViewModelFactory("user123"))
19 .get(UserViewModel::class.java)
20
21// Usage with by viewModels()
22private val viewModel: UserViewModel by viewModels {
23 UserViewModelFactory("user123")
24}
Sharing ViewModel Between Fragments
1// SharedViewModel.kt
2class SharedViewModel : ViewModel() {
3 val selectedItem = MutableLiveData<String>()
4}
5
6// FragmentA — sets the value
7class FragmentA : Fragment() {
8 private val sharedViewModel: SharedViewModel by activityViewModels()
9
10 fun onItemSelected(item: String) {
11 sharedViewModel.selectedItem.value = item
12 }
13}
14
15// FragmentB — observes the value
16class FragmentB : Fragment() {
17 private val sharedViewModel: SharedViewModel by activityViewModels()
18
19 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
20 sharedViewModel.selectedItem.observe(viewLifecycleOwner) { item ->
21 textView.text = item
22 }
23 }
24}
Gradle Dependencies
1dependencies {
2 // Core lifecycle (required)
3 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0"
4
5 // For by viewModels() in Activity
6 implementation "androidx.activity:activity-ktx:1.8.2"
7
8 // For by viewModels() and by activityViewModels() in Fragment
9 implementation "androidx.fragment:fragment-ktx:1.6.2"
10
11 // Optional: SavedStateHandle support
12 implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0"
13}
Migration Checklist
1// Step 1: Remove old import
2// import androidx.lifecycle.ViewModelProviders ← DELETE
3
4// Step 2: Add new import
5import androidx.lifecycle.ViewModelProvider
6// or for delegates:
7import androidx.activity.viewModels
8import androidx.fragment.app.viewModels
9import androidx.fragment.app.activityViewModels
10
11// Step 3: Replace all usages
12// OLD: ViewModelProviders.of(this).get(MyViewModel::class.java)
13// NEW: ViewModelProvider(this).get(MyViewModel::class.java)
14// BEST: private val viewModel: MyViewModel by viewModels()
Common Pitfalls
Missing activity-ktx or fragment-ktx dependency: The by viewModels() delegate is an extension function in activity-ktx and fragment-ktx. Without the dependency, the compiler reports "Unresolved reference: viewModels".
Using by viewModels() vs by activityViewModels(): by viewModels() in a Fragment creates a ViewModel scoped to that fragment. To share state between fragments, use by activityViewModels() which scopes the ViewModel to the parent activity.
Accessing ViewModel before onCreate: by viewModels() is lazy — it creates the ViewModel on first access. Accessing it before onCreate (e.g., in property initializers) causes a crash because the ViewModelStore is not yet available.
ViewModelProviders class not found at compile time: If you updated the lifecycle dependency but still reference ViewModelProviders, the class is not in the new artifact. Remove all references and replace with ViewModelProvider.
Custom factory with by viewModels(): The lambda in by viewModels { factory } must return a ViewModelProvider.Factory. Returning the ViewModel directly causes a type mismatch error.
Summary
Replace ViewModelProviders.of(this).get(VM::class.java) with ViewModelProvider(this).get(VM::class.java)
Use by viewModels() Kotlin delegate for the cleanest, lazily-initialized syntax
Use by activityViewModels() to share a ViewModel between fragments
Add activity-ktx and fragment-ktx dependencies for the delegate extensions
Pass a ViewModelProvider.Factory for ViewModels that need constructor parameters