Last week's was a difficult post to write, which discussed issues of racism, bias, and privilege (and a new feature of Android Studio). This time, I want to share my story of migrating from RxJava 2 -> 3.
Staying current with the libraries you use in your app is essential to maintaining a secure, performant application. One such library is RxJava, which fairly aggressively releases new versions and deprecates old ones. RxJava 1 is now officially no longer supported, and even RxJava 2 will only continue to receive updates (critical security patches, etc.) until February of 2021. If you remember the RxJava 1 -> 2 migration, you may remember it was fairly painful - many things were renamed, and dropping support for
null values in streams often required a lot of refactoring and cleanup to avoid runtime crashes.
The good news is, the RxJava 2 -> 3 migration is much more straightforward! The RxJava team has a very helpful article highlighting the differences: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-3.0
Here is the approach I took when migrating:
Convert all gradle imports from RxJava 2 to RxJava 3 (
Try to compile! You will likely see some errors. Then, start fixing them one-by-one. Here are some of the ones I ran into:
- The 4-argument
Observablehas been removed - if you need to specify what happens on subscribe, use the
Flowable/Observablehas been split into multiple variants - either
Maybehas been replaced by a different function (originally called
flatMapSingleElement()) - to achieve the previous behavior, now just call
Timedclass now throws a runtime Exception if you try to pass in
nullfor the initial value.
assertNotTerminated(), and several other
TestSubscribermethods have been removed, as they were determined to really only be useful internally to the RxJava library itself.
accept()method for the
Consumerclass now throws a
Throwableinstead of an
onErrorResumeNext()method has been renamed to
- The methods in the
Disposablesclass have been merged into the
As a result of this upgrade, some other related libraries also needed to be updated, including:
- RxLifecycle (to version 4+) (Gradle import + package rename to
- RxDogTag (to version 2+) (Gradle import + package rename to
- RxRelay (to version 3+) (Gradle import + package rename to
- RxJavaInterop (to version 3+) (Gradle import + package rename to
- Retrofit (to version 2.9+) (Gradle import, package rename to
retrofit2.adapter.rxjava3, and a new call adapter -
- RxAndroid (to version 3+) (Gradle import + package rename to
One last thing - if you find yourself needing to interface with older RxJava code (from other libraries - hopefully your app is consistent and uses the same version everywhere), there are two helper libraries you should know about:
RxJavaInterop (converting from RxJava 1 <-> 2/3): https://github.com/akarnokd/RxJavaInterop
RxJavaBridge (converting between RxJava 2 <-> 3): https://github.com/akarnokd/RxJavaBridge
I find it slightly irritating that these are separate libraries, but these are both VERY helpful if you want to keep your app on a single version of RxJava, as not all libraries have been updated to use RxJava3 yet - for instance, RxLifecycle, Retrofit, and RxRelay have all only been updated with RxJava 3 support in the last month.
So, if you have a little time on your hands, RxJava 3 now seems ready for primetime use! And thankfully, my own experience was that this conversion was fairly painless - the entire conversion was completed within 1 work day.
Please share your own experiences/tips for making the leap to RxJava 3, and let me know if you have any questions! And, please follow me on Medium if you're interested in being notified of future tidbits.
This tidbit was discovered on June 10, 2020.