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:

Kotlin: list.forEach { process(it) }
Java 8: list.forEach(it -> process(it))

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;
  • Properties, primary constructors and data classes greatly reduce the amount of boilerplate in the code representing the data model of your application:
    data class User(val name: String, val groupId: String = "default")
  • 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:

As you see, Kotlin has lots and lots of things to offer to make you more productive, beyond what Java 8 can offer to a Java 6 developer. And it’s also easy to learn, with comprehensive documentation, interactive exercises and books covering both Kotlin in general and the use of Kotlin for Android development. So if you haven’t tried Kotlin yet, now is as good time as any!

This entry was posted in Android, Roadmap. Bookmark the permalink.

31 Responses to Kotlin’s Android Roadmap

  1. Stepan Goncharov says:

    Sounds very good! Any goodies for DataBindings with Kotlin?

  2. Pingback: 【はてなブックマーク】Kotlin’s Android Roadmap | Kotlin Blog – 気になるニュースをお届け♪

  3. Nik says:

    What about kapt plugin?
    It is still extremely buggy.

    • yanex says:

      Do you have any specific problems? If yes, could you submit an issue?
      Also, some of them are already fixed, and the fixes will be present in the upcoming 1.0.2 release.

      • Nik says:

        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)

      • I have specific problems, I’d like to see fixed soon:

        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…

      • ken says:

        I’ve seen a problem w/ nested annotations where it doesn’t use the @ for the nested annotation. e.g., translating this
        @Table(database = TestDatabase.class,
        indexGroups = {
        @IndexGroup(number = 1, name = “firstIndex”),
        @IndexGroup(number = 2, name = “secondIndex”),
        @IndexGroup(number = 3, name = “thirdIndex”)
        })
        doesn’t work as you’d expect.

  4. antimule says:

    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.

    • Dmitry Jemerov says:

      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.

      • AW says:

        Also, Kotlin’s existing DSL features can already replace ad-hoc code generators in a large number of scenarios.

        Are there any examples of this?

  5. Kuba says:

    I am waiting for “Extract string resource” option integrated into Kotlin. This would be very useful for me

  6. Dmitry Gordeev says:

    Thanks guys for your amazing work!

    Are you going to support other static analyzers like FindBugs?

    • Dmitry Jemerov says:

      FindBugs is an analyzer that works on bytecode, and you can use it today on bytecode generated by Kotlin. I don’t see what additional support would be needed from the Kotlin team.

  7. Pingback: Around the web: Episode #5 | GX Consultancy – Blog

  8. Misha says:

    Any plans for adding typeclasses? I mean interfaces that can be implemented for some data type outside of definition of that type.

  9. Pingback: Issue #199 | 神刀安全网

  10. Anton says:

    Would be great to have SonarQube support as a part of tooling chain. At the moment there is no plugin for Kotlin files and .kt classes are ignored by UI completely

  11. What is the status of using Jack & JILL for compiling? Is it planned, in works or not considered at all?

  12. Hafiz Waleed Hussain says:

    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

Comments are closed.