Flow… But Not That Flow

The point behind device controls is to give the user an accessible UI for manipulating some device via your app — a thermostat, an overhead door, a lamp, etc. There may be some delays involved in your app finding out the current state of the device and in changing that state via the user’s interaction with these tiles. Plus, the state often might change via other inputs, such as somebody pushing a button or flipping a switch, so you might need to deliver state changes over time.

This calls for an asynchronous API, where you can have some time to deliver responses, use background threads, and so on.

You might think that Google would use LiveData here. However, LiveData is specifically designed for dealing with lifecycles, and there isn’t really a “lifecycle” involved with this work. Plus, LiveData is a Jetpack library, and framework classes like ControlsProviderService cannot depend upon Jetpack libraries.

You might think that given Google’s strong interest in Kotlin that they would use coroutines, such as Flow. However, while Google overall is Kotlin-friendly, the framework is not. Google’s coroutine-centric APIs are all in Jetpack libraries. The device controls API needs to be more readily usable by Java apps.

You might think that Google would go “retro” and use callbacks or listeners, since they are still all over the place in the Android SDK. Or, perhaps they would use some sort of Future or one of the seemingly-endless number of classes and interfaces named Observable.

Instead, they chose to use the Reactive Streams API… somewhat.

The Reactive Streams API is a cross-platform initiative for defining reactive APIs. Android 11 includes the JDK 9 edition of an API based on Reactive Streams, in the form of interfaces like Flow.Publisher, used to provide a stream of results to some subscriber.

However, Android 11 does not include an implementation of Reactive Streams, just the API embodied in those interfaces. The expectation is that you will use a third-party library that can provide implementations of those interfaces, where the leading contender for this is RxJava.

If your project already uses RxJava, great! However, the Reactive Streams classes in RxJava may be different than the ones that you are used to. In RxJava, typically we use Observable and Subject, but the Reactive Streams RxJava equivalents are Flowable and Processor. Still, the concepts are fairly similar.

If your project does not use RxJava right now… you get to start! Isn’t that fun!

(narrator: it will not be fun, but many Android developers use RxJava successfully, so you will be able to do so as well)


Prev Table of Contents Next

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