Kotlin’s Android Roadmap

Introduction

One of the most interesting pieces of news we’ve all seen recently is Google announcing (limited) Java 8 support for Android N with the Jack compiler for Java. Naturally, our users are curious about how these news affect them, and this blog post outlines our plans and our vision for Kotlin’s place in the Android development world in light of Google’s announcements.

Kotlin’s Roadmap for Android

We pay a lot of attention to making Kotlin a good tool for Android development. In the next few releases (1.0.X) we will continue improving our toolchain and libraries. Our current efforts are focused on three main areas: speeding up the development workflow, reducing the size of the runtime library and providing more complete tooling support.

Development Workflow

To speed up the development workflow, incremental compilation is coming to Kotlin’s Gradle plugin. This will improve the build times considerably: when a source file is changed, we’ll only recompile this particular file and those files really depending on it, not the whole module.

The next thing we plan to do to improve Android build performance is providing an integration with Android’s new Jack and Jill toolchain. Right now there are some issues that prevent Jack from handling Kotlin-generated bytecode correctly (196084 and 203531), but we plan to work together with the Google team to either resolve the issues or provide workarounds on our side. Once this is done, we’ll be able to translate only changed class files using Jill during incremental compilation, as opposed to translating all class files every time (which is the only possible behavior in the old Android tooling).

Last, but not least: Instant Run. Currently, Cold Swap works fine for Kotlin, but Warm and Hot Swap require some further investigation. We’ll do what we can to get them fixed ASAP. In the meantime, JRebel for Android works fine with Kotlin already.

Runtime Size

We are planning several improvements to reduce the methods count of kotlin-stdlib. Our current result is 7’191:

Optimizing top-level functions representation in multi-file facade classes and moving inline-only functions out of the runtime-available binary will win us several thousand methods.

Tooling Support

The main thing missing from Kotlin 1.0’s Android support story is Lint Checks, and we’re happy to announce that they are coming to Kotlin. We have already implemented all the checks available in Android Studio 1.5 (planning to publish them in Kotlin 1.0.2), and the new 2.0 checks are on the way. Our Lint checks are built on top of a common representation of Kotlin and Java code, and we plan to contribute that representation to the Android SDK, so that new checks added in future versions of the Android SDK will work with Kotlin out of the box.

More Android-specific IDE support, such as a New Kotlin Activity action, code insight and navigation features, and others will also be added gradually as 1.0.X releases are published.

Kotlin and Java 8

Java 8 has been around for quite a while now, and thus many of our users, those who are not doing Android development, have chosen Kotlin over Java 8 and are happy about it. Now that Android has official support for the Java 8 language features, how does that change the decision of choosing between Kotlin and Java?

First of all, while Java 8 does bring lambdas to Android, there are important differences between the way the Android toolchain supports lambdas on existing platform versions (that don’t run the N release) and the way Kotlin supports lambdas. To understand the difference, let’s see how the following simple code snippets are compiled:

Java’s version is a tiny bit longer, but let’s not focus on that. Instead, let’s see what happens under the hood. Starting with Java:

in Android’s Java 8 every lambda is compiled to a class, which has two methods: constructor and the actual body (affecting the method count of your application);

this class is later instantiated at runtime, in many cases — every time the forEach is called (creating pressure on the garbage collector);

and to access it, Java uses a polymorphic call to Consumer.accept, which may happen on every iteration in a tight loop (affecting performance, because the runtime cannot always inline such calls).

Kotlin, in the general case, implements lambdas in exactly the same way. However, in many cases, including most collection operations such as forEach, Kotlin generates much more efficient bytecode through the use of inline functions. When you use an inline function with a lambda, both the body of the function and the lambda are inlined at the call site. As a result:

the bytecode of the lambda is inserted directly into the bytecode of the calling method, so the method count does not increase;

executing the code does not allocate any objects, so there is no garbage collector pressure;

the resulting bytecode does not contain any polymorphic method calls, ensuring the best possible execution speed at runtime.

Bottomline: lambdas in Java 8 on Android are not at all free, and one should probably think twice every time and choose between good code and performance. In Kotlin, the need for such compromises is greatly reduced, and you can use lambdas as much as you need to express the ideas in your code.

And of course, Kotlin has many other language features which are not available in any version of Java. Just to list a few:

Support for null-safety prevents most of the NullPointerException problems in your code, saving you from the dreaded “Unfortunately, application has stopped” message;

Delegated properties allow to extract the common logic in property getters and setters and to put that into a library:val imageData by lazy { loadData(imageFile) }

And the DSL construction features of Kotlin give you an entirely new level of flexibility in building your application which is simply not available in Java. For example, it gives you the option to replace XML layouts with an embedded DSL and to describe the UI of your application in the same language as the rest of the code, with full access to the abstraction features of the language. Here’s how this can be accomplished using the Anko library:

Thanks, i’ll try 1.0.2
Usually the problems are not specific and random: sometimes it builds ok, but has lost classes/methods. Sometimes build failed until ‘clean’. Universal solution is ‘clean’ task. But it takes a lot of time, so incremental compilation became useless.
ps: I use Dagger2, Databindings, Butterknife, Parcelabler, Dart/Henson, Realm, DBFlow (not simultaneously though)

1) kapt often fails to update generated classes, as a result I often have either a compilation error or NoSuchMethod error at runtime. This happens with Dagger2: whenever I change some module or component (I do not recall exact steps at the moment)

2) It is not possible to have the same-named functions or fields targeted by annotations. For example it is not possible to have “@Provides fun providePresenter()” functions in 2 (or more) Dagger modules, compilation will fail. It is also not possible to have 2 ButterKnife “@Bind textView: TextView” in 2 (or more) different activities – for the same reason. This is even more irritating, field names are far more seen/used than dagger’s provider methods.

IIRC there are bugs filed for both of these problems, but it seems fixes won’t get in 1.0.2. I hope to have them fixed soon and I wish there were some comments from kotlin devs or target versions set in YouTrack for them…

Are there any plans at all for a macro system in Kotlin? I know they have a reputation but there are reasons. For one, it would dramatically increase expressiveness without adding any runtime overhead at all. Second, it would completely eliminate the need for ad-hoc code generators. Third it would reduce the need to constantly add new features. In addition, it is very much in step with the whole DSL theme.

No, at this time we have no plans to create a macro system for Kotlin. For us, clarity takes a much higher priority than expressiveness, and the experience of macro systems in other languages shows that they often have a very high cost in terms of clarity. Also, Kotlin’s existing DSL features can already replace ad-hoc code generators in a large number of scenarios.

Hi. I am new born baby for Android. I am working from last 4 years but I am confuse. I want to know If I ask you, can I start working with kotlin what will be your answer. Because I want to implement Unit tests, Funtional tests using espresso and then I want to implement CI. So what is your recommendation. Thanks