DEV Community

Harsh Lade
Harsh Lade

Posted on

3

Android Architecture Components: ViewModel, Lifecycle.

Introduction

Welcome back! In the last article, we explored an overview of Android Architecture Components and patterns. Now, let’s zoom into two key players: ViewModel and Lifecycle. These tools help your app handle data and UI states like a pro—think surviving screen rotations or knowing when your app is active. Ready to dive in?

ViewModel: Saving Your Data

What is ViewModel and Why do we use it?

ViewModel is your app’s data guardian. It stores UI-related data that might otherwise disappear during configuration changes—like when a user rotates their screen. Without it, your app’s state resets, frustrating users.

Here’s an example: Imagine a counter app. You set a Text view to "0" and increment it with a Button. After five clicks, it shows "5." But rotate the screen, and boom—it’s back to "0" because the Activity restarts. ViewModel prevents this by keeping the count safe across these changes.

How to use ViewModel

Step 1. add the dependency.

Paste this line in your build.gradle (Module level)

    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
Enter fullscreen mode Exit fullscreen mode

Note: If using Jetpack Compose, use lifecycle-viewmodel-compose instead.

Step 2. Make a ViewModel class.

Make a class that extends ViewModel to hold your data:

class MyViewModel : ViewModel() {
    var count by mutableStateOf(0)  // State in ViewModel
        private set  // Only ViewModel can modify it

    fun updateCount() {
        text++ // Update state
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3. Set up in your App.

Now use the MyViewModel class in your app to show the count value on your UI.


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp()
        }
    }
}

@Composable
fun MyApp(viewModel: MyViewModel = viewModel()) { 
//viewModel() function provides the instance of MyViewModel.
    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "${viewModel.count}")
        Button(onClick = { viewModel.updateCount() }) {
            Text("Click Me")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Run it, click a few times, and rotate the screen—the count sticks around!

Lifecycle: Tracking Your App’s States

LEvery Activity or Fragment has a lifecycle—stages like creation, visibility, or destruction. Think of it like a human life: born (onCreate), active (onResume), resting (onPause), or gone (onDestroy). Knowing these states lets you control what happens when—like saving data before the app closes.

Here’s a quick example:

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Lifecycle", "onCreate called")

        setContent {
            MyApp()
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d("Lifecycle", "onStart called")
    }

    override fun onResume() {
        super.onResume()
        Log.d("Lifecycle", "onResume called")
    }

    override fun onPause() {
        super.onPause()
        Log.d("Lifecycle", "onPause called")
    }

    override fun onStop() {
        super.onStop()
        Log.d("Lifecycle", "onStop called")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("Lifecycle", "onDestroy called")
    }
}
Enter fullscreen mode Exit fullscreen mode

Check your Logcat as you open, minimize, or close the app—each state logs a message!

Lifecycle Observer

Want to react to lifecycle changes without overriding methods? Use a Lifecycle Observer. Here’s how:

Here is how we use Lifecycle Observer and Owner.

class MyObserver : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        Log.d("LifecycleObserver", "Activity started!")
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        Log.d("LifecycleObserver", "Activity stopped!")
    }
}
Enter fullscreen mode Exit fullscreen mode

In above code, we are inheriting DefaultLifecycleObserver to define an observer. Inside the observer we are implementing our tasks.
Now, we need to attach the observer with our activity, here is how do we do it.

@Composable
fun MyComposable() {
    val lifecycleOwner = LocalLifecycleOwner.current
    val observer = remember { MyObserver() }

    DisposableEffect(lifecycleOwner) {
        lifecycleOwner.lifecycle.addObserver(observer)
        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
        }
    }

    Text("Hello, Lifecycle!")
}
Enter fullscreen mode Exit fullscreen mode

Here, LocalLifecycleOwner.current provides the instance of Lifecycle Owner of current activity.
DisposableEffect() is a side-effect function that gets created when the composable starts and gets destroyed when the activity gets disposed.
lifecycleOwner.lifecycle.addObserver(observer) it is adding the observer we made above.
lifecycleOwner.lifecycle.removeObserver(observer) it removes the observer when activity gets disposed.

Conclusion

We’ve unlocked ViewModel to preserve data and Lifecycle to track UI states. Together, they make your app resilient and smart. Next up, we’ll tackle LiveData to keep your UI in sync with changing data. See you there!

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (1)

Collapse
 
mubaraknative profile image
Mubarak Native • Edited

ViewModel is your app’s data guardian.

Linking something (VM is a android recommended architecture component, for storing UI states and simple business logic) or redirect to official docs would be great for absolute beginners apart from this your high level example is great.

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay