Android
ViewModelProviders
Deprecated
Jetpack
Android Development

ViewModelProviders is deprecated in 1.1.0

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

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

kotlin
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)

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
// Java
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);

The cleanest approach using Kotlin property delegates:

kotlin
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:

kotlin
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

kotlin
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

groovy
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

kotlin
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

Course illustration
Course illustration

All Rights Reserved.