At Google I/O this year, Google announced a new set of architecture libraries. One of the new components they included is called LiveData. It can be used to help manage propagating data to your views, while respecting the activity and fragment lifecycles. Until now, you typically had to manage all of this on your own. Or more commonly, many developers neglected to handle these scenarios at all. This resulted in memory leaks, among other issues.
In the past, I wrote about how to make an event bus with RxJava. I also wrote about how you could send events without the event bus using RxJava and Dagger. I had mentioned that if you’re not careful about managing these subscriptions, it can easily lead to memory leaks. If you have other developers using your code, you don’t want to rely on them knowing exactly how your code works. It should be as foolproof as possible.
To set up the event bus, we need to implement LifecycleRegistryOwner on our Activities and Fragments. To simplify this, I have a BaseActivity class, and a BaseFragment class which can be extended from. These classes will implement the LifecycleRegistryOwner interface, so all of my Activities and Fragments don’t have to. You can see these implementations below:
The other piece is my LiveData class. I want to be able to send any type of data through my event bus, so I will use the Object class for my LiveData. I named my implementation EventLiveData:
My event bus uses integer constants to define different subjects. These subjects are what define the type of event you are observing. When your LifecycleRegistryOwner is destroyed, its Observers will be removed. I override the
removeObserver method so that the EventLiveData can remove itself from the event bus.
The reason I remove the EventLiveData from the event bus, is because it will send out whatever its current value is to new observers. This behaviour is fine if you’re loading data, but I’m also using it to send events like tapping on a button. I don’t want those events to get repeated.
With these components included, my new event bus class looks like this:
To use the LiveDataBus, you subscribe to a subject with a LifecycleRegistryOwner (typically a Fragment or Activity). Then, implement the Observer callback to do whatever you want with the data. Since the bus uses Objects, you need to cast it to whatever type of data you’re receiving. Here is an example:
The way that I am using LiveData is not how it was intended to be used. But, it does exactly what I need - it takes care of the lifecycle issues for me. Now I don’t have to worry about my event bus causing memory leaks, or any other lifecycle problems. Especially if someone other than me is using this code. Now, it’s foolproof!