Android
ViewModel
AndroidViewModel
MVVM
Android Architecture Components

AndroidViewModel vs ViewModel

Master System Design with Codemia

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

Introduction

ViewModel and AndroidViewModel solve the same core Android problem: keeping UI-related state alive across configuration changes while keeping activities and fragments thin. The difference is that AndroidViewModel also exposes the Application object, and that extra capability is useful in a few cases but overused in many codebases.

What a ViewModel Is For

A regular ViewModel is lifecycle-aware state holder code that survives rotation and other configuration changes. It should own presentation logic and state, not direct references to activities, fragments, or views.

Typical responsibilities include:

  • exposing UI state through LiveData, StateFlow, or similar streams
  • launching coroutines for repository calls
  • transforming domain data into screen data
  • handling user actions that affect the current screen state

A simple Kotlin example:

kotlin
1class ProfileViewModel(
2    private val repository: UserRepository
3) : ViewModel() {
4
5    private val _uiState = MutableStateFlow(ProfileUiState())
6    val uiState: StateFlow<ProfileUiState> = _uiState
7
8    fun loadUser(id: String) {
9        viewModelScope.launch {
10            val user = repository.loadUser(id)
11            _uiState.value = ProfileUiState(name = user.name)
12        }
13    }
14}

This is the default choice for most screens.

What AndroidViewModel Adds

AndroidViewModel is just a ViewModel subclass with one extra feature: it receives the Application instance in its constructor.

kotlin
1class SettingsViewModel(
2    application: Application
3) : AndroidViewModel(application) {
4
5    private val prefs = application.getSharedPreferences("settings", Context.MODE_PRIVATE)
6
7    fun isFirstRun(): Boolean {
8        return prefs.getBoolean("first_run", true)
9    }
10}

That makes it possible to access app-wide resources, preferences, or objects that need application context.

The important detail is that the provided context is the application context, not an activity context. That means it is safe for long-lived objects and does not create the same leak risk as keeping a direct activity reference.

When to Prefer ViewModel

In modern Android architecture, prefer plain ViewModel unless you truly need the Application object. Most dependencies should be injected from outside through a repository layer, dependency-injection framework, or factory.

For example, instead of reaching into Application to construct a database inside the ViewModel, inject the repository that already depends on the database:

kotlin
1class TasksViewModel(
2    private val repository: TaskRepository
3) : ViewModel() {
4
5    val tasks = repository.observeTasks()
6}

This is easier to test, easier to refactor, and keeps the ViewModel focused on state rather than object wiring.

When AndroidViewModel Makes Sense

AndroidViewModel is reasonable when the model genuinely needs application-scoped context and there is no cleaner way to inject the required dependency.

Examples include:

  • reading from a simple preference store in a small app
  • accessing app resources that depend on locale or configuration
  • bootstrapping a lightweight dependency that requires Application

Even then, many teams still prefer constructor injection of a wrapper or repository rather than subclassing AndroidViewModel directly.

Testing Tradeoffs

Plain ViewModel is usually easier to unit test because it only depends on explicit constructor arguments. AndroidViewModel often drags in framework concerns and can tempt developers to mix Android resource access with screen logic.

If you find yourself mocking Application frequently, that is usually a sign the screen state layer depends on too much Android framework code.

Common Pitfalls

The most common mistake is choosing AndroidViewModel just because it sounds more powerful. In many projects it becomes a shortcut for grabbing context everywhere, which weakens separation of concerns.

Another pitfall is storing activity or fragment references in a ViewModel. Neither ViewModel nor AndroidViewModel should hold short-lived UI objects.

Developers also sometimes use context-dependent APIs in a plain ViewModel by passing an activity context into it. That works until it leaks or becomes hard to test.

Finally, do not forget that surviving configuration changes does not mean surviving process death. For restorable values, pair ViewModel with SavedStateHandle or another persistence strategy.

Summary

  • Use plain ViewModel by default for screen state and presentation logic.
  • Use AndroidViewModel only when you truly need application context.
  • Prefer dependency injection over reaching into Application from the state layer.
  • 'ViewModel is usually easier to test and keeps architecture cleaner.'
  • Neither type should hold references to activities, fragments, or views.

Course illustration
Course illustration

All Rights Reserved.