Level Up Your Android Architecture: Say Goodbye to ViewModelProviders ๐Ÿš€

Modernize your dependency injection and state management using property delegates and Hilt.

Level Up Your Android Architecture: Say Goodbye to ViewModelProviders

If you’re still using ViewModelProviders.of(this).get(MainViewModel::class.java), it’s time for a quick intervention. That API isn't just "old school"—it’s officially deprecated as of Lifecycle 2.2.0.

Modern Android development focuses on conciseness, type safety, and lifecycle awareness. Moving to Kotlin property delegates is one of the easiest wins for your codebase. Here is your modern migration blueprint.

๐Ÿšซ The Ghost of Android Past

The old way of initializing ViewModels required unnecessary ceremony. It forced you to handle the provider instance manually just to get a simple reference.

Before vs. After

// ❌ THE DEPRECATED WAY (Verbose & Manual)
val viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)

// ✅ THE MODERN WAY (Lazy & Type-safe)
private val viewModel: MainViewModel by viewModels()

✅ The Modern Way: Kotlin Property Delegates

By using the activity-ktx and fragment-ktx libraries, you unlock delegates that handle the heavy lifting for you.

1. The viewModels() Delegate

This is for a ViewModel scoped to the current LifecycleOwner (the Activity or the Fragment itself). It is lazy-loaded, meaning it won’t be initialized until it’s actually accessed.

class UserProfileFragment : Fragment(R.layout.fragment_user_profile) {

// ๐Ÿš€ Clean and lazy-loaded
private val viewModel: UserProfileViewModel by viewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

viewModel.userData.observe(viewLifecycleOwner) { user ->
// UI updates automatically
}
}
}

2. Sharing State with activityViewModels()

This is the gold standard for managing shared state between fragments. Instead of complex interfaces, both fragments point to the same instance scoped to their parent Activity.

// In both Fragment A and Fragment B:
private val sharedViewModel: SharedDataViewModel by activityViewModels()

๐Ÿ›  Quick Migration Checklist

  • [ ] Replace ViewModelProviders.of() with viewModels() or activityViewModels().
  • [ ] Use ViewModelProvider(this) only for Java or specialized legacy code.
  • [ ] Prefer SavedStateHandle over manual constructor arguments for state restoration.
  • [ ] Use shared ViewModels for state; use the Fragment Result API for one-off events.
  • [ ] Annotate ViewModels with @HiltViewModel to eliminate factory boilerplate entirely.

⚠️ Common Pitfalls to Avoid

  • Wrong Owner: Using viewModels() in a fragment when you meant to share data with another fragment (use activityViewModels() instead).
  • Memory Leaks: Observing LiveData/Flow with this instead of viewLifecycleOwner in fragments.
  • Over-sharing: Using activityViewModels() for one-time navigation events.
  • Manual Factories: Reintroducing complex factory logic when Hilt or SavedStateHandle can do it automatically.

๐Ÿ›‘ When NOT to Use Shared ViewModels

While powerful, activityViewModels() isn't a silver bullet. Avoid it for:

  • Cross-Activity communication: ViewModels cannot be shared between two different Activities.
  • Deeply nested flows: Where the lifecycle owner becomes ambiguous or too broad.
  • One-off UI signals: Use the Fragment Result API for “success/failure” callbacks instead of storing them in a persistent state.

๐Ÿ™‹‍♂️ Frequently Asked Questions (FAQs)

Do I still need a ViewModelProvider.Factory?

Rarely. With Hilt or SavedStateHandle, the default factory handles most cases. You only need a manual factory for unique, non-injectable runtime dependencies.

Does activityViewModels() work across different Activities?

No. It scopes the instance to the current host Activity. Navigating to a new Activity creates a fresh instance.

What are the required dependencies?

implementation "androidx.activity:activity-ktx:1.8.2"
implementation "androidx.fragment:fragment-ktx:1.6.2"

๐Ÿ’ฌ Let’s Discuss!

  • Have you fully migrated to KTX delegates, or is the old ViewModelProviders still hiding in your modules?
  • Do you prefer activityViewModels() for communication, or are you a Fragment Result API fan?
  • How has the combination of viewModels() and Hilt changed your development speed?

Drop a comment below and let’s talk shop!

๐Ÿ“˜ Master Your Next Technical Interview

Since Java is the foundation of Android development, mastering DSA is essential. I highly recommend “Mastering Data Structures & Algorithms in Java”. It’s a focused roadmap covering 100+ coding challenges to help you ace your technical rounds.

Comments

Popular posts from this blog

No More _state + state: Simplifying ViewModels with Kotlin 2.3

Why You Should Stop Passing ViewModels Around Your Compose UI Tree ๐Ÿšซ

Is Jetpack Compose Making Your APK Fatter? (And How to Fix It)