Lifecycle-Aware components with Kotlin — Android Architecture Components

Marcos Sandoval
5 min readAug 22, 2018

Every component introduced by Google is intended to be a solution to a bad/not good situation or a performance/code improvement. In this case, we want to discuss all problems that can come if we don’t use the lifecycle of the Android components properly.

Which are the problems?

  • You are creating an app that plays video/music streaming from internet, you need the app to start buffering the media since it’s open, but playback until it is fully started. Probably you want to stop the video and buffering if the app is on the background and restart it when it comes up to the foreground. Finally, you need to cancel the playback and buffering when your app is closed and also release all the resources at this time.
  • You were asked to develop an app that tracks the user’s location as soon as the user opens your app. Your app has to show the user’s location on the screen if it is on the foreground or to store it in the database if it is not on the foreground. Also, when the app is closed you have to stop tracking the user’s location and release all the resources.
  • You have an app that requests and sends information to a server in the background to keep both synchronised. This flow of data should start right after the user opens the app, but we also want to know when the user sends the app to the background, closes it or performs any action on it. This synchronization has to be done at least every 5 minutes, and should be stopped when the app is closed.

Until now the way to handle this kind of situations is adding operations to the lifecycle callbacks of the dependent component (Activity, Fragment, Service, etc), but this approach ends up in a poor organization of code, it is difficult to maintain and it can generate a bunch of errors.

Most of the app components that are defined in the Android Framework have lifecycles attached to them. Lifecycles are managed by the operating system or the framework code running in your process. They are core to how Android works and your application must respect them. Not doing so may trigger memory leaks or even application crashes.

With the knowledge that we have until now, the normal way to handle the cases mentioned above is as follows:

AuditHelper.kt

This class is in charge to track any action done on the app, this includes when the app is started, paused and stopped.

MainActivity.kt

To report the requested actions we need to play with the lifecycle callback of the Activity like shown below.

This doesn’t look so bad, but in real apps we will end up with a lot of operation being executed on the callbacks and probably all of them are part of different components (class, service, etc) without any relationship between them. Also, it is completely your responsibility of execute the correspondent operation on the right callback so you release the resources when they are not need and avoid memory leaks or execute the right operation when a specific state is reached. It sounds very prone to errors, right? Well, LifeCycle-Aware components come to the rescue.

Lifecycle-Aware components

These components, officially released on January 22th, 2018, are intended to help handling in a more elegant way the operations that depend on the lifecycle. Lifecycle components react to changes on the lifecycle status of other components that are subscribed to observe, helping us to have better organized code, increasing the modularity, encapsulation and maintainability, and reducing the possibility to introduce errors or memory leaks.

Lifecycle-Aware components can be any of the following types:

  • LifecycleOwner: An interface that represents a class that has Android lifecycle, like Activity, Fragment or Service. Also, it can be implemented in a custom class as we will see below.
  • LifecycleObserver: An interface that denotes a class that is observing any state change on the LifecycleOwner it subscribes to observe. Also, LifecycleObserver uses OnLifecycleEvent annotation to subscribe its methods to observe specific component state change.

Let’s go to the code

We are going to refactor the examples we showed above to make them lifecycle aware.

Before we start, all the sample codes are written using kotlin, if you don’t know Kotlin or you want to learn more, I would like to invite you to visit this link and read my article about it. Also, if you want learn about Room, the Android Architecture Components for persistence, and simplify the way of how you interact with SQLite on your apps, I strongly recommend you to visit my article and learn more about this incredible component.

Ok, let’s see the code. The first thing we need to do is to update our gradle file. It should look like the following:

App.gradle

As we mention above, lifecycle aware components can be: LifecycleObserver or LifecycleOwner. Let’s start with our LifecycleObserver:

AuditHelperLifecycleAware.kt

Things to be noticed here:

  • We need to implement the LifecycleObserver interface, this marks a class as a LifecycleObserver. It does not have any methods, instead, it relies on OnLifecycleEvent annotated methods.
  • We use the annotation @OnLifecycleEvent to indicate that the method needs to be notified when a specific event occurs. For instance, we are indicating we want that the method auditStated() be executed each time the LifecycleOwner, we subscribed to, goes to the state STARTED and so on.

Now, let’s go the our LifecycleOwner, in this case we are going to use an Activity which extends AppCompatActivity that implements LifecycleOwner interface.

MainActivityLifecycleAware.kt

Things to know:

  • At the line 9, we are getting the lifecycle of the activity. Since AppCompaqActivity implements LifecycleOwner interface, we can get its lifecycle easier.
  • activityLifecycle.addObserver(auditHelper!!) method allows us to indicate we want our AuditHelperLifecycleAware instance to be notified of the state changes of this LifecycleOwner. The parameter addObserver method receives have to be a class that implement LifecycleObserver interface.
  • activityLifecycle.addObserver(auditHelper!!) method allows us to indicate we want our AuditHelperLifecycleAware instance to be notified of the state changes of this LifecycleOwner. The parameter that addObserver method receives has to be a class that implements LifecycleObserver interface.

And that’s it, with a better organized code we are able to be aware of the changes of state of an Activity and react to this changes.

But hold on, that’s not all. What if I want to have my own LifecycleOwner? Don’t worry, you can do it without write tone of code. Lets see an example:

CustomLifecycleOwner.kt

Things to be noticed:

  • Our custom lifecycleOwner has to implement the LifecycleOwner interface and implement the method getLifecycle() as shown above.
  • lifecycle.markState(state: State) allow us to setup the current state of the class; triggering the lifecycle callbacks so the observers can react to the state changes.
  • lifecycle.markState(state: State) allow us to setup the current state of the class; triggering the lifecycle callbacks so the observers can react to the state changes.

And that’s all. We learned how to create lifecycle aware components, which is the difference between a LifecycleOwner and LifecycleObserver, how to use each of them and how implement our custom LifecycleObserver.

The whole code of the project can be gotten from here. Thanks for reading, if this article was useful or entertaining for you please clap it, share it and follow me. :)

--

--