Leverage Java 8 features alongside RxJava in your next Android Project and stay safe while doing it with the new Android Studio 2.4

Published Jul 07, 2017

Who else is excited about the new features in Android studio 2.4, this article was supposed to be about my frustrating experience with the Jack Toolchain and RetroLambda. Then 

Google recently announced built-in support for Java 8 features in new Android Studio 2.4 preview, and recommend migrating from Retrolambda and Jack. 
I installed this preview release alongside the existing stable one. You can check out how to do this here.
Migrating is easy, it is just removing the retrolambda dependencies or removing the jackOption{ … } block in build.gradle

My build time has incredibly decreased, I’ve achieved build time of a little more than a min with lots of more Java 8 features.

I’d like to share my frustrating experience with using the Jack Compiler and some cool features of Java 8 with RxJava that lured me into this danger.

So I decided to use Java 8 features in a small Android Project I’m working on, being that I haven’t used any Java 8 feature on android and knowing fully well that Android doesn’t support this features before the release of Nougat. You can check out cool features of Java 8 here.

So I made some research and found out I could enable this feature with a few lines of code in my build.gradle.

With the Jack Compiler and RetroLambda, I’m scared of building apks because of the thought that something might be broken or that gradle build time might take several minutes to complete

jackOptions { enabled true}compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8}

Cool right.

That big boy feeling came alive when I first replaced all the usual boilerplate code of setting onClick listeners with lambdas , I mean this

sayHelloButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { shoutHello(); }});


sayHelloButton.setOnClickListener(view -> shoutHello());

Also, method referencing made this method calls even clearer, you can replace the above snippet with this

Observable.just("Hello, world!") .subscribe(s -> System.out.println(s));

instead of this

Observable.just("Hello, world!") .subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } });

RxJava comes with a huge bunch of operators, allowing us to chain as many calls as we want together, fine-tuning the data into a perfect form to be consumed by the end Subscriber. Consider the example below

query("key") .flatMap(urls -> Observable.from(urls)) .flatMap(url -> getTitle(url)) .filter(title -> title != null) .take(5) .doOnNext(title -> saveTitle(title)) .subscribe(title -> System.out.println(title));

Suppose query is defined as follows,

Observable<List<String>> query(String text);

Let’s go over this in detail

query() returns an observable that emits a list of urls.
flatMap() transforms the urls emitted by the Observable from query() into Observables of each url , and then flatten the emissions from the Observables into a single Observable. so we get a single url at a time.
flatMap() transform this observable into another observable that emits the title retrieved from each url. Also we get that one at a time.
filter() emits the title it received, but only if title is not null.
take() sets the maximum number of titles that we want. Here it’s 5.
in doOnNext(), we save the title in a repository. 
And lastly in subscribe() we add an observer that prints each title to console.

We are making multiple calls and adding more flavors and manipulating the data easily. 
Also, we don’t have to be worried about the danger of Callback hell, as we are certain that the current operation ends before the next one is invoked. This takes care of common issues faced by developers while making lots of asynchronous calls in their code.

If the above example is not very clear, don’t be scared, it took me awhile before I understood this too and I still get confused about RxJava sometimes too. But I strongly recommend you check Dan Lew’s series on RxJava here.
Also, check out the last section below for further readings.

I enjoyed cool stuff about RxJava

Then the dark-side sets in as I decided to build my project and gradle’s build time went from 30 secs — 1 min to 7-16 mins. The Jack compiler is much slower than the legacy Javac + dx. Build time increased as I added more Java 8 feature so I looked into it and found out other issues:

Instant Run is not supported.

Annotation processing is not supported, so tools like DexGuard, Jacoco is not supported. This might affect some libraries that use Annotation Processing.

All these issues were solved by simply installing the Android Studio 2.4 Preview. You can check out how to do this here.> NOTE: It is not recommended to replace a stable version of AS with a preview version as it is still under test and might have a new bug. So I’ll recommend you keep both versions.

If you are including Java 8 feature in your new or existing project, I’ll recommend that you consider this option to save yourself the trouble caused by Jack and RetroLambda.

Further Reading

Java 8 Language Features on Android

Future of Java 8 Language Feature Support on Android | Android …

Jack And Jill Are Google’s New Compilers For Android App Developers

More information on RxJava

Discover and read more posts from Kanyinsola Fapohunda Oyindamola
get started