Other LiveData Examples

Let’s take a look at a few more examples of using LiveData, to explore other facets of how this can be used.

Event Bus

LocalBroadcastManager implements an in-process event bus, where events are delivered to you on the main application thread, and where “events” are Intent objects.

You can accomplish the same thing, with greater flexibility, by means of a LiveData object, as can be seen in the General/LiveBus sample project.

This sample app is derived from one shown in The Busy Coder’s Guide to Android Development, where we have AlarmManager triggering a service. In principle, that service should do some work, which we are skipping here because we are lazy. However, the fake work is something that the user might care about, and so we want to let the UI layer know about the event if we happen to be in the foreground. Otherwise, we want to raise a Notification. In The Busy Coder’s Guide to Android Development, implementations of this sample are available for a few event buses, including LocalBroadcastManager and greenrobot’s EventBus.

Here, though, we will use a MutableLiveData singleton:

  static final MutableLiveData<Intent> BUS=new MutableLiveData<>();

MutableLiveData is a subclass of LiveData, with one key feature: it offers a postValue() method that works like setValue() but can be called from a background thread. Here, our events are in the form of Intent objects, the way they would be for LocalBroadcastManager. However, you could create your own custom event objects if you prefer, and typically that would be a better idea. In this case, the sample is demonstrating a quick-and-dirty change from LocalBroadcastManager, so we are keeping the event objects the same to reduce the number of code changes.

The service, as part of its work, asks the BUS whether there are any active observers, by means of hasActiveObservers(). If hasActiveObservers() returns true, we use postValue() to post the event onto our BUS. Otherwise, we raise a Notification, as our UI is not in the foreground.

Our EventLogFragment registers an observer lambda on the BUS, adding the events to its ArrayAdapter:

    ScheduledService.BUS.observe(this, intent -> adapter.add(intent));

Unlike LocalBroadcastManager, this approach performs no Intent filtering, and we can have as many MutableLiveData objects as needed. So, you can create custom buses for different event channels, instead of using action strings as you might with LocalBroadcastManager.

Room

Having DAO methods in Room return a LiveData is simply a matter of setting them up that way:

  @Query("SELECT * FROM Customer WHERE postalCode IN (:postalCodes) LIMIT :max")
  LiveData<List<Customer>> findByPostalCodes(int max, String... postalCodes);

Now, findByPostalCodes() will return a LiveData. Moreover, it will do so immediately when called, with the actual query being performed on a Room-supplied background thread. You can arrange to register an observer to find out when the results are ready. And, by using the same LiveData instance after a configuration change, you can get the last-loaded results without having to perform another round of disk I/O.

However, Room has an additional feature: if you make changes to the database through your DAO, Room will deliver fresh results to any registered observer of your LiveData. So, for example:

In effect, Room attempts to give you ContentObserver capabilities, for your own database, tied directly into the LiveData system.

Note, though, that these changes are tied in large part to your use of the DAO. For example, if you want to insert 100 entities, you could:

Doing things in batch form generally will be more efficient, both from a disk I/O standpoint and a LiveData-updating standpoint. On the other hand, this means that a LiveData update might represent several changes, and that may require additional smarts to handle properly in terms of updating the UI (e.g., use DiffUtil to efficiently update a RecyclerView).

We will see using LiveData with Room in the next chapter.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.