UI Persistence with ViewModels in Android Kotlin

Master UI Persistence with ViewModels in Android Kotlin: A Comprehensive Guide

android-viewmodel-example
Android ViewModel


Introduction:

Android development involves building applications for devices running the Android operating system. It offers a dynamic and versatile platform but comes with specific challenges.

One key challenge is managing UI data across configuration changes. This happens when the device changes like:
  • Screen rotation: Portrait to landscape and vice versa.
  • Keyboard visibility: Appearing or disappearing.
  • Language/Locale: Switching between languages.

These changes cause the system to recreate your app's activities and fragments. Without proper data management, your app could lose data, display outdated information, or behave unexpectedly.

Several strategies address these issues:
  • SavedInstanceState: Activities and fragments can save data in a bundle before recreation and restore it later.
  • ViewModel: An architecture component specifically designed to store and manage UI data, persisting through configuration changes.
  • Jetpack Compose: A modern UI framework using composables that automatically handle configuration changes.

What are ViewModels?

Imagine building a complex mobile app, where users navigate seamlessly between screens and the UI remembers its state like a trusty companion. This smooth experience lies in the hands of a powerful tool: ViewModels.

ViewModels are the data champions of the MVVM (Model-View-ViewModel) architecture. They act as intermediaries, storing and managing UI-related data independently of the View (activity or fragment). 

This independence grants them superpowers:
  1. Configuration Change Champions: No more losing data during screen rotations or device restarts! ViewModels survive these changes, ensuring your UI picks up right where it left off.
  2.  Lifecycle-Aware Heroes: They seamlessly integrate with the Android lifecycle, automatically cleaning up resources and preventing memory leaks. No more manual handling, just pure data bliss.
  3. Separation of Concerns Superstars: By keeping UI data separate from the View, ViewModels promotes cleaner code and easier testing. Focus on the data logic, leaving the View to shine with its visual magic.

Key Considerations and Best Practices:

  • Data Storage:
    • Store the necessary data within the ViewModel. This can be any data relevant to the UI component, such as user input, fetched data from a database or network, etc.
    • ViewModels hold data in memory during the lifecycle of their associated UI component (typically an activity or fragment). This data remains available as long as the UI component is active and has a reference to the ViewModel.
    • To overcome the limitation of data loss during process deaths, developers often use persistence solutions such as databases (e.g., Room), shared preferences, or caching mechanisms. These persistence solutions allow data to be stored persistently on the device's storage, ensuring that it can be retrieved even after the application process is killed and restarted.
  • LiveData:
    • LiveData is often used in conjunction with ViewModels to hold and expose data to UI components. ViewModels typically expose LiveData instances as properties, allowing UI components to observe changes in the ViewModel's data seamlessly.
    • LiveData allows UI components (like activities or fragments) to observe changes in data held by the ViewModel. This observation is done in a lifecycle-aware manner, meaning that UI components only receive updates when they are in an active state, preventing unnecessary UI updates.
  • Testing:
    • ViewModels often interact with repositories, services, or other data sources. By isolating these dependencies within the ViewModel and using interfaces or dependency injection, it becomes easier to mock these dependencies during testing. This enables thorough testing of ViewModel behavior under various data scenarios.
    • Since ViewModels are not tied to the Android framework, they can be easily instantiated and tested in isolation from the UI components. This allows for more efficient unit testing of the business logic and data manipulation within the ViewModel using standard testing frameworks like JUnit.

Building Your First ViewModel

Let's create your first ViewModel in Android using Kotlin.

Step 1: Add ViewModel dependency to your build.gradle file

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"

Step 2: Create your ViewModel class

Create a Kotlin file for your ViewModel, for example, MyViewModel.kt.
import androidx.lifecycle.ViewModel

class MyViewModel : ViewModel() {
    // Define your ViewModel data and methods here
}

Step 3: Accessing the ViewModel in Activity/Fragment

In your Activity or Fragment, initialize your ViewModel and observe its data.
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.Observer

class MainActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Observe data from ViewModel
        viewModel.myData.observe(this, Observer { data ->
            // Update UI with the new data
            // For example:
            // textView.text = data
        })

        // Trigger a method in ViewModel
        viewModel.loadData()
    }
}

Step 4: Update ViewModel to hold data and methods

Update your ViewModel class to hold data and methods that your Activity/Fragment can interact with.
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class MyViewModel : ViewModel() {

    private val _myData = MutableLiveData<String>()
    val myData: LiveData<String> = _myData

    fun loadData() {
        // Simulate loading data from a repository
        val newData = "Hello, ViewModel!"
        
        // Update LiveData
        _myData.value = newData
    }
}

Step 5: Update your layout file (if needed)

Make sure to update your layout file (activity_main.xml) with any UI components you want to interact with.

That's it! You've created your first ViewModel in Android using Kotlin. This ViewModel is responsible for holding and managing your UI-related data and logic, separate from the UI controller (Activity or Fragment).

Advanced Topics

Conclusion

That's a basic overview of how to use ViewModels in Android with Kotlin. They are a powerful tool for organizing and managing UI-related data in a way that promotes separation of concerns and improves the maintainability of your code.

Thanks for reading this article. Hope you would have liked it!. Please share and subscribe to my blog to support.

Pragnesh Ghoda

A forward-thinking developer offering more than 8 years of experience building, integrating, and supporting android applications for mobile and tablet devices on the Android platform. Talks about #kotlin and #android

1 Comments

Please let us know about any concerns or query.

Previous Post Next Post

Contact Form