Categories
android architecture blog kotlin

Building a podcast app series: 2. Player state

After the view is set up, it’s very important to have a model that will drive that UI, something that we can observe and render our UI according to its state. It would be nice to react to model changes with some kind of a listener and it would be great if we don’t have to manually subscribe/unsubscribe to this model. Luckily, Android has a ViewModel class that is built for this exact purpose.

ViewModel

View modes are a relatively new invention. Before ViewModels came along, and the whole AAC (android architecture components), representing ViewModels in a clean and safe way was particularly tricky. Android activity or a fragment can be in multiple states and properly connecting/disconnecting a particular activity or a fragment is a dance around onCreate / onDestrory, onResume / onPause, and other lifecycle methods. Since our in-app player view is visible on all screens, wee need a globally accessible state holder for that player. Luckily, a ViewModel is all we need to safely share the player state across different fragments. Since we are using a single activity pattern, ViewModels are automatically tied to that activity and can be shared across fragments! This means that we can easily tell other views what is the state of our in-app player by just sharing a ViewModel across multiple fragments! Oh, by the way, ViewModels survive configuration change, so that is also being taken care of.

So, how do we create a new view model? We can simply write in any fragment

private val playerViewModel by sharedViewModel<PlayerViewModel>()

The basic idea here is that ViewModels do not care who is using its LiveData, it can be a single fragment or bunch of them, it does not matter. ViewModels should not reference any Fragment or Activity, they simply expose data for Views to observe!

If you are curious about the code for the PlayerViewModel check out this link.

LiveData

Once we have a shared state holder for our player, we need a safe way to update our views. That is where LiveData comes in, it is a safe container for any kind of data. And the best part about LiveData is that it automatically knows if our fragment or activity is active and can receive updates, so we don’t have to handle that logic ourselves! This means no more null pointer exceptions of illegal state exceptions. We are free to post new data to LiveData and be sure that nothing will crash as a result of that.

How do we create and update live data?

private val _currentlyPlaying = MutableLiveData<Episode>()
currentlyPlaying.value = currentEpisode

Repository pattern

The last piece of the state puzzle is to identify where does our data come from? In a simple word: from a Repository of Podcasts! Repository pattern is such a simple pattern and very useful. We can make our Repository do a bunch of interesting things. We can cache data to the local DB, we can mock our data, we can fetch something from the internet, everything related to data and its retrieval is hidden behind our Repository class.

How does a simple repository look like?

class PodcastRepository {
    fun getPodcasts(): List<Podcast> =
        listOf(Podcast("The Joe Rogan experience"))
}

Basic setup for every screen

In conclusion, every screen in our app will reference ViewModels and will subscribe to LiveDatas. ViewModels will fetch data from Repositories and update LiveDatas and we have a reactive setup for each screen in our app. Error handling is done in the same manner, we just have a LiveData of error messages where we can push errors and observe them inside Fragments.

Browse the full code on this link. Stay tuned for the next article in this series where we explore exoPlyaer, brains behind any podcast app.

Categories
android architecture blog design kotlin

Android architecture components with Kotlin

Introduction

After Google announced android architecture components, it was, for the first time, a Google-approved android architecture guidelines. Before this, the whole community would try to come up with best ways to structure android apps. First, everyone tried to follow MVC pattern that Google sort of provided with Android. But MVC for android is very confusing, you have a controller who is a view also (Activity, Fragment). Then MVP came along. model view presenter architecture, which clearly separates responsibilities of views and presenters (controllers). The main idea was to define interfaces (responsibilities) for each view and its presenter, making the app much easier to refactor down the road, given the fact that you know exactly what are responsibilities of each screen. One downside for MVP is the total amount of interfaces you have to create and maintain.
When reactive java came along, it turned everything upside down. MVP did not fit quite well with rxJava, since data is reactive, you do not have to specify what happens when data changes, you just map it to the view and the view became reactive to its data. With reactive programming, you react to changes in the app, whether its user input or network fetching and the view is this dummy representation of that data. It turned out, that reactive programming is perfect for Android, since events are something that is very natural to mobile phones, it became much easier to write and maintain complex UIs with rxJava. So what are downsides to rxJava? Spaghetti code, if you can not recognize when to use rxJava, it is very easy to write spaghetti code.
So what exactly does architecture components bring to the table?

Architecture components overview

Before we look into what architecture components offer, what problems do they solve, let’s look at common issues Android developers face.

  • Configuration change (device rotation),
  • Synchronized UI with data
  • Fetching data from database
  • … (lots more)

Let’s start with the configuration change, what would be a proper way to solve this problem? In my opinion, I want no memory leaks :D, then I would like the data to survive the change, I don’t want to fetch data again just because a user rotated the screen. So we need some kind of lifecycle aware component which survives the configuration change, knows when it can update the activity, but also knows when to destroy itself when it is not needed anymore. This is exactly what ViewModel class is. With few lines of code, you can have a UI that reacts to data changes and also display the latest data when UI gets recreated.
What about UI synchronization? That is where LiveData comes in. Once you create a LiveData instance, you can subscribe to it, and receive updates every time you update that LiveData instance.
What about the database? There are plenty of ORM libraries out there, do we need another one? Well, what if you want an ORM which returns a LiveData, which you can subscribe to it, so when you insert new data into the database, you get updates immediately? That is where Room comes in.
Those are the building blocks of Android architecture components, but the question remains, what about Android architecture? These components serve a specific purpose, how to structure the whole app now?
Well, just follow MVVM architecture, the View reacts to ViewModel, which exposes Models for Views to use and update their representation. Instead of wiring the Views to Models manually, Data-Binding library can be used to that automatically. So what we described above is just a Google recommended/provided implementation of the required components for MVVM architecture.

Github repository

I made a Github repository for a sample project that uses Kotlin and android architecture components, check it out to see how everything fits together in one app. Here are the main specifications of the project in that repository:

  • ViewModel for reactive data binding
  • Room as ORM library
  • Paging Library as a reactive data source for adapters
  • Dagger 2 as dependency injection framework
  • Repository pattern for data fetching
  • Retrofit as a REST client