Android Studio Moves Toward Java 8
Written by Mike James   
Tuesday, 18 April 2017

Android Studio is making progress to supporting Java 8 after the ambitious, perhaps too ambitious Jack & Jill project was shelved. What does all this mean?

Version 2.4 of Android Studio is heading towards a release candidate. at which point we will all get the opportunity to try out some Java 8 features - one in particular that new Android programmers have been asking about for some time, lambdas. 

The latest version, preview 6, supports a surprising number of Java 8 features considering the short time that has elapsed since the Jack & Jill compiler project was deprecated. The problem is that while Android uses supposedly standard Java it compiles it to a different byte code. The standard Java compiler is used to convert to standard Java byte code and then dx is used to convert this to Dalvik byte code or Dex.

The problem is that dx only translates a subset of the byte code and specifically not enough to implement Java 8 features. The Jack & Jill compiler project was an attempt to create an entirely new compiler that went directly from Java to Dalvik byte code. This would have been an even bigger split from Java and this is ostensibly the reason the project has been shelved.

jackcomp

Now the plan is to extend the dx compiler to one called desugar to compile the extra features in the byte code needed to implement Java 8. 

android8

 

The latest Android Studio preview includes a good range of Java 8 features and most important of all you will almost certainly be able to use lambdas in the next stable release. 

What does this mean to the average Android programmer?

The biggest impact, as mentioned, is likely to be lambdas. The reason is that Java has long had a problem with its lack of first class functions. If you want to pass a function in Java you have to pass an object that has the function as a method. This makes event handling in Java very wordy and almost incomprehensible to a programmer coming from almost any other langauge. Adding lambdas makes event handling much easier. 

For example, suppose you have a Button with the id button, then to attach a simple click event handler you need to use:

Button b=(Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
           ((Button)v).setText("You Clicked Me");
         }
});

 

This uses an anonymous class to create an instance of OnClickListener with an overridden onClick method.

Notice that's a class and instance of a class and a method just to pass a function to setOnClickListener.

It isn't as bad as it sounds because Android Studio will do a lot of the work for you by generating the boilerplate code. There is an easier way to create an event handler for the click event, but this only works for the click event.

Using lambdas is much more direct:

Button b=(Button) findViewById(R.id.button);
b.setOnClickListener(v->{b.setText("You Clicked ME!");});

This just passes a function to the setOnClickListener. Of course, the compiler wraps the function in an instance of a class. but this is all behind the scenes and the programmer can ignore it. Before you think that there is an error in that b is used and not v in the lambda, it is worth also pointing out that this is a closure and the lambda has access to the variables that were in scope when it was created. However, it isn't good to cache references to UI objects so a better version is:

Button b=(Button) findViewById(R.id.button);
b.setOnClickListener(v->{((Button)v)
                      .setText("You Clicked ME!");});

It will be interesting to find out if any Android programmers in the future know what an anonymous class is.

You can also use method references which allow you to reference an existing method as the body of a lambda thus allowing you to pass an existing method without passing the entire class. 

You can also use type annotations but only at compile time not run time and if you are prepared to give up instant run you can use default and static interface methods. Shame because default methods are very useful. 

Also if you are prepared to use API 24 or higher you can use:

java.lang.annotation.Repeatable

AnnotatedElement.getAnnotationsByType(Class)

java.util.stream

java.lang.FunctionalInterface

java.lang.reflect.Method.isDefault()

java.util.function

To make use of these features you have to disable Jack and any other library you are using to make up for a lack of Java 8 support. You also have to add:

compileOptions { 
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8 
}

to the module's build.gradle file. After this you can use Java 8 in a new project in older projects there may be more to do. 

Let's hope that in the final version we just have a dropdown for the language level. 

Android Studio is still changing too fast in some respects and not fast enough in others. Why for example am I still having to use findById and not data binding as default?

And why is it all still so slow?  

android8icon

 

More Information

Use Java 8 language features

Related Articles

Google's Jack & Jill Android Java Compiler Project Is Dead

The New Android Compilers - Meet Jack And Jill 

Android Studio 2.3 - In Need Of Direction

Android Studio 2.2 Preview Big Changes! 

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

Banner


Improved Code Completion With JetBrains Mellum
29/10/2024

JetBrains has launched Mellum, a proprietary large language model specifically built for coding. Currently available only with JetBrains AI Assistant, Mellum is claimed to provide faster, sm [ ... ]



Tcl/Tk 9 Released
01/10/2024

Tcl/Tk 9 has been released with changes including 64-bit capacity, and improvements to the handling of Unicode and encodings.


More News

 

espbook

 

Comments




or email your comment to: comments@i-programmer.info

<ASIN:187196251X>

Last Updated ( Tuesday, 18 April 2017 )