Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Introduction to Android App Development With Kotlin: LiveData (Part 10)

DZone 's Guide to

Introduction to Android App Development With Kotlin: LiveData (Part 10)

Meet LiveData, the observable data holder class that is ''lifecycle aware.''

· Java Zone ·
Free Resource

With the ability to retrieve data from your database, it seems appropriate that we display those records for the user to see in a fragment. At this stage, you may be wondering: how do we effectively return this list of movies from the view model to the fragment? Or maybe you are thinking: what should happen if I make a call to the database and, at the same time, the user decides to leave my app to do something else? Should we return the data nonetheless and waste resources or should we not. Luckily, there’s a Google’s Android library we can use that will handle all those awkward edge cases for us. Hello, LiveData

In this tutorial, we will look into LiveData, what exactly it is, and how it fits into our application.

LiveData

 LiveDatais an observable data holder class that is lifecycle aware. “This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.”

Main advantages of using LiveData:

  • Ensures your UI matches your data state
  • No memory leaks
  • No crashes due to stopped activities
  • No more manual lifecycle handling

At this stage, it’s clear that this library will make our life easier so how do we go about using it? Luckily, we don’t have to import it because it comes included as part of lifecycle-extensions, which we imported when we first started working with the view model.

Here’s the method I use for using LiveData, which makes the most sense to me. 

First, in the view model, let’s add a private instance variable of type MutableLiveData:

val allMovies = MutableLiveData<List<Movie>>()


 MutableLiveData object type is almost the same as LiveData object except it exposes two important methods, namely setValue(T) and  postValue(T), which we will use. 

Next, we will slightly upgrade the retrieveMovies() method to return a LiveData object. We will return the allMovies instance variable we created above but downcasted to LiveData since a fragment has no business updating it. 

fun retrieveMovies(): LiveData<List<Movie>> {

    GlobalScope.launch {
        val list = mDb?.movieDao()?.getAll()
        Timber.i("retrieveMovies list count ${list?.size}")
        allMovies.postValue(list)
    }

    return allMovies
}


Notice how we are also using the postValue method to notify the observers (i.e. our fragment) of the fetched data. 

Finally, it’s time to subscribe to this LiveData object in the MovieListFragment. In the line where we called the retrieveMovies() method, all we have to add is add an observer to it

mViewModel.retrieveMovies().observe(this,  Observer {

    Timber.i("received the movies ${it.size}")

})


Run the app and watch the results

Image title

We are now observing the data using LiveData! You must admit, it was quite simple yet very powerful. The fact that we don’t have to worry about activities or fragments lifecycle is a huge relief. You can now apply this pattern to all of the data calls you will ever need to make. 


Conclusion

Today, we were introduced to an awesome library called LiveData and we put it to use. With a concrete implementation, you can now easily replicate it to add any calls to the database you may need. 

With the movies list available to us within the fragment, we should now display it. The way to do it is by using a recyclerview. More about that in the next tutorial.

The complete working code can be found in this GitHub repo where each lesson is tagged appropriately.

Topics:
android app development ,kotlin 1.3 ,livedata ,recyclerview ,mvvm ,room database ,Java ,kotlin

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}