Leverage Java 8 features alongside RxJava in your next Android Project and stay safe while doing it with the new Android Studio 2.4
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();
}
});
with
sayHelloButton.setOnClickListener(view -> shoutHello());
Also, method referencing made this method calls even clearer, you can replace the above snippet with this
sayHelloButton.setOnClickListener(this::shoutHello);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