Introduction to Android Architecture Components with Kotlin — Room, LiveData
In the previous article MVP Architecture with Kotlin — Dagger 2, Retrofit, RxAndroid and DataBinding, we have seen how to implement such an architecture. In today’s article, we will see how to add Architecture Components to that project.
The project we will develop
We will start from the application as it was at the end of the previous article. The source code is available on the GitHub repository of the Feed-Me project.
It is a simple application developed around an MVP architecture that displays a list of posts from the JSONPlaceholder API.
We would like to add some features to this project:
- If there are no posts in database, then retrieve posts from the API then store them in database.
- If there are posts in database, then displays posts from the database.
I know this is not actually the behaviour of a real news app, but the aim here is just to show implementation of Architecture Components.
We will start Architecture Components implementation with Room. This library allows us to store data in a database. To use it, we have first to add it to the module dependencies:
Now that it is done we will edit a little bit our
model.Post POJO class in order to add anotations that will tell Room the description of the table associated to this class:
Let us now add a project an object with the role of accessing the database. We will name it
PostDao and we will add it to
model package. This main purpose of this class will be to be able to retrieve list of
Post from the database, and insert
Post in it:
All we have to do now is to add an abstract class for the Database itself that we will call
FeedMeDatabase placed at the
The next step will be to manage dependency injection so the presenter will be able to access Dao instances. That is why we will add a
DaoModule class in
Now, let us add the
DaoModule to the modules of
Last thing to do about dependency injection is to add the
DaoModule to the instantiation of the
Now that the structure has been done, let us apply it in our final presenter. First thing to do in the
ui.post.PostPresenter class is to split the
loadPosts() method into two methods, as we don’t want to always load posts from the API:
Now let us store posts retrieved from the API in the database. It is quite easy with all the structure we have made:
Now, we want that method to be called only if there is no post in database. This one also is quite easy, and quite the same as we did:
Feel free to try the application now. You should need an Internet connection the first time you run it, but you can switch to flight mode for next runs.
Okay, our application matches with our first needs. But there is something that I don’t like in the current code. Actually for now we update list of posts only in one place in the presenter. But this code would be complicated to maintain if we would update list of posts in many places of the Presenter. Just imagine pagination or pull to refresh… It would force us to add boilerplate code. To avoid this, Architecture Components provides LiveData.
Add Library Dependency
In order to be able to use LiveData features, we first need to add the dependency to that library in the
build.gradle file of the module:
MutableLiveData is a class that allows us to observe a value, and run some code when that value is updated. Let us start by adding a
MutableLiveData property to the
We have now to change the value of the
mutablePostList when the list of posts is actually retrieved:
What we have to do now is to add an observer to the value so we can call
view.updatePosts() when the value is updated. LiveData’s very cool feature is that it is lifecycle aware. You don’t have to tell when to start listening (when Activity is resumed) and when to stop (when Activity is paused). All you have to do is to pass a
LifecycleOwner to the listener and LiveData will do the rest.
LifecycleOwner but we have to tell that our
BaseView also implements it. Let’s do it:
Now we can add the observer into the presenter and tell the observer to update posts in the view when the value is updated. All we have to do is to instantiate an
Observer (be carefull, a LiveData Observer, not an RxJava one), and to tell the mutable data to notify the Observer when its value changes:
You can now run your application and see that everything is working like a charm. But please consider this article only as an introduction to Architecture Components, because Architecture Components are much more than just Room and LiveData, and can be extremely powerful in an MVVM architecture.
All the code source of the project as it is at the end of this post is available on architecture_components_intro branch of Feed-Me repository on GitHub.
If you liked this article, feel free to follow me on Twitter to get notified about next ones.