ViewModel & LiveData
Survive configuration changes with ViewModel. Expose reactive data streams with LiveData and observe them in Activities and Fragments.
ViewModel & LiveData is a free Android Academy lesson on CoddyKit — lesson 1 of 6. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, one of 6 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Problem with Activities
Storing data directly in an Activity has two major problems:
- When the user rotates the phone, the Activity is destroyed and recreated — all your data is lost
- If you fetch data from the network in
onCreate, it re-fetches on every rotation — wasteful
ViewModel solves both problems.
What Is ViewModel?
ViewModel is an Android Architecture Component that:
- Survives configuration changes (rotation, theme change)
- Holds UI-related data and business logic
- Is destroyed only when the user permanently leaves the screen
Rule of thumb: if data should survive rotation, put it in a ViewModel.
Creating a ViewModel
Extend ViewModel and add it to your Gradle dependencies:
// app/build.gradle:
// implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
// implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.7.0'
import androidx.lifecycle.ViewModel
class CounterViewModel : ViewModel() {
var count = 0
private set
fun increment() {
count++
}
fun reset() {
count = 0
}
}Getting a ViewModel in Activity
Use ViewModelProvider (or the by viewModels() delegate) to get a ViewModel instance:
import androidx.activity.viewModels
class CounterActivity : AppCompatActivity() {
private lateinit var binding: ActivityCounterBinding
// Android manages the ViewModel lifecycle — never instantiate it yourself
private val viewModel: CounterViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityCounterBinding.inflate(layoutInflater)
setContentView(binding.root)
// This shows the count is preserved after rotation!
binding.tvCount.text = viewModel.count.toString()
binding.btnPlus.setOnClickListener {
viewModel.increment()
binding.tvCount.text = viewModel.count.toString()
}
}
}What Is LiveData?
LiveData is an observable data holder. The UI observes LiveData values, and the UI updates automatically when the value changes.
- Lifecycle-aware — only updates active observers (no crashes when Activity is in background)
- Always up-to-date — new observers get the latest value immediately
LiveData in ViewModel
Use MutableLiveData privately (ViewModel can write), expose it as LiveData publicly (UI can only observe):
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class CounterViewModel : ViewModel() {
private val _count = MutableLiveData(0)
val count: LiveData<Int> = _count // read-only for the UI
fun increment() {
_count.value = (_count.value ?: 0) + 1
}
fun reset() {
_count.value = 0
}
}Observing LiveData in Activity
Call .observe(lifecycleOwner) { value -> } to react to changes:
class CounterActivity : AppCompatActivity() {
private val viewModel: CounterViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
// Automatically updates TextView whenever count changes
viewModel.count.observe(this) { count ->
binding.tvCount.text = count.toString()
}
binding.btnPlus.setOnClickListener { viewModel.increment() }
binding.btnReset.setOnClickListener { viewModel.reset() }
}
}LiveData vs State Flow
LiveData is the classic approach. Modern Kotlin code often uses StateFlow from Kotlin Coroutines instead:
StateFlow— coroutine-based, no Android dependency- Collected with
repeatOnLifecyclein the Activity - Better for complex state management
Both work well — LiveData is simpler to start with; you'll see StateFlow in larger apps.
ViewModel with Multiple Observers
Multiple UI components can observe the same LiveData. For example, both a TextView and a Button's enabled state can react to the same data value in the ViewModel — without any extra code in the ViewModel.
This separates concerns cleanly: ViewModel holds state, UI just observes and renders.
Quick Check
When is a ViewModel destroyed?
Recap: ViewModel & LiveData
You now know how to build lifecycle-aware UIs:
- ViewModel survives configuration changes (rotation)
- Use
by viewModels()to get a ViewModel in an Activity - MutableLiveData (private) / LiveData (public) pattern
- Observe with
.observe(this) { value -> updateUI(value) } - UI updates automatically — no manual refresh needed
Next: persist data permanently with the Room database.
Frequently asked questions
Is the “ViewModel & LiveData” lesson free?
Yes — the full text of “ViewModel & LiveData” is free to read here on the web, and the Android Academy course includes 6 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Android Academy course, upgrade to CoddyKit PRO.
What will I learn in “ViewModel & LiveData”?
Survive configuration changes with ViewModel. Expose reactive data streams with LiveData and observe them in Activities and Fragments. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Android Academy?
No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 6, so you can start here or from the beginning and move at your own pace.
How long does the “ViewModel & LiveData” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Android Academy lesson?
Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.