2 min read

RxAndroid 2.1.0, the latest version of RxAndroid, has an option to post async messages. The async parameter affects Android APIs 16 and newer. It allows one to avoid VSYNC locking that pushes every post to the next frame.

RxAndroid adds minimum classes to RxJava to make reactive programming in Android applications easy and hassle-free.

Why this change is introduced?

The main thread has historically used Handler#post() to schedule new Messages. This follows the VSYNC locking and results in waiting until the next frame to run. Use of Handler#post() causes a delay of up to 16ms for every emission to go through the post().

This delay happens even if you’re already on the main thread. The Async API aims to bypass VSYNC locking while still letting the framework handle all the scheduling safely in its looper.

How you can install the Async API?

With the help of RxAndroidPlugins you can set async as the custom scheduler.

In Kotlin:

val asyncMainThreadScheduler = AndroidSchedulers.from(Looper.getMainLooper(), true)

RxAndroidPlugins.setInitMainThreadSchedulerHandler { asyncMainThreadScheduler }

// Or if the default scheduler is already
initialiazedRxAndroidPlugins.setMainThreadSchedulerHandler { asyncMainThreadScheduler }

In Java:

Scheduler asyncMainThreadScheduler = AndroidSchedulers.from(Looper.getMainLooper(), true);

RxAndroidPlugins.setInitMainThreadSchedulerHandler(callable -> asyncMainThreadScheduler);

// Or if the default scheduler is already initialiazed

RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> asyncMainThreadScheduler);

How asynchronous is enabled in the different Android APIs?

The Async API works by relying on the new Handler.createAsync factory in API 28, and on pre-28 it will reflectively fall back to a private constructor of Handler to enable this.

  • API 28: The Handler.createAsync() factory API is used. It sets all Messages it handles to be asynchronous by default.
  • API 22+: The public setAsynchronous() method is used.
  • API [16–21]: The setAsynchronous() method is still used but the lint error that says it’s only 22+ is suppressed. To avoid any OEM situations of deleted/changed internal APIs, the Message#setAsynchronous() method call is handled using try/catch in the from() Scheduler factory to ensure it’s there at runtime. This catches the NoSuchMethodError if it is missing and falls back to the standard non-async messaging.
  • API <16: There is no behavior change and the standard non-async messaging is used since the asynchronous APIs didn’t exist.

To know more about the Async API head over to Zac Sweers announcement on Medium.

Read Next

Entry level phones to taste the Go edition of the Android 9.0 Pie version

Android 9 pie’s Smart Linkify: How Android’s new machine learning based feature works

Dagger 2.17, a dependency injection framework for Java and Android, is now out!

LEAVE A REPLY

Please enter your comment!
Please enter your name here