Post Google I/O: The State of Android Development [UPDATED]
A few weeks ago i posted an analysis of the current state of the gradle based Android build system. Today we are living in a post Google I/O 2013 world and several things have changed. Time for an update. The most prominent change is the new Android development environment: Android Studio.
Currently in its infancy at version 0.1, the new IDE is based on the (free) community edition of IntelliJ IDEA. IntelliJ is widely accepted as a very good Java IDE and has lots of followers. IntelliJ provided Android support itself but this has now been replaced with the “official” extensions provided by Google. Watch the Google I/O talk about Android Studio for more details. The interesting question is: Why did Google invest in yet another development environment next to the Eclipse ADT? After all you were able to download a standalone runnable version of the ADT as well. “People close to the matter” cite several reasons for such a step.
IntelliJ is a great IDE
Obviously i am working for a very Eclipse centric company. Nonetheless i must admit that there is a lot to love about IntelliJ. While the Eclipse Java development components have not seen a lot of innovation lately, IntelliJ keeps on pushing usable features. Better autocompletion, better suggestion prediction and a more flexible editor system helps to boost productivity. In addition several features of IntelliJ/Android Studion go beyond what Eclipse/ADT offers. To name a few:
Resource Inlining (Also works for images)
Implementation folding (Similar to Lambda expression in Java 8)
Parameter prediction (Correct constants are proposed for int parameter)
The features described here will eventually become part of the Eclipse/ADT framework but at the moment this is not the case. In addition Android Studio offers superior visual layout editing and preview features, full gradle project configuration, support for build flavors etc.
On the other hand, many features that developers are used to from the ADT are not yet (natively) in Android Studio: All DDMS tools, dumping the layout hierarchy for the UI Automator etc. These features will be implemented in future releases.
The Android build story is broken (on Eclipse)
While Eclipse is able to compile and export an Android app, it has no idea of a build system. Building Android projects was and still is a mess. Google realized that and started developing a new build infrastructure based on gradle. The new build system strives to unify the project setup in a development environment as well as on a build server. Both scenarios should be driven by one configuration that is very customizable for various product scenarios (free vs paid app etc.). Gradle provides a great foundation for this undertaking and the build system it is on its way to maturity.
While the approach is great in theory, it posed a problem when integrating the system into Eclipse. Since gradle is supposed to completely build the project, the continuous incremental compiler of Eclipse had to be circumvented. This turned out to be a technical challenge that was hard to overcome.
With IntelliJ, the compiler only kicks in when you “make” an application, which made the IntelliJ integration simpler. In addition gradle (and maven) are already first class citizen and so it was much easier to integrate the build hooks into IntelliJ. Side note: In Android Studio gradle runs on hot-standby so it kicks in much quicker than simply invoking a build manually.
Jetbrains (the company behind IntelliJ) supported Google in the integration process and made adjustments for them when necessary. The result is build story which is able to cover the entire round trip from project creation to a release build on the build server. On the way you get: import and setup in the ide, dependency management, awareness of build types and product flavors, export from the IDE and the ability to query your build scripts (a gradle feature).
The most interesting feature is the creation of the “Android SDK Build-tools” as part of the Android SDK. The Build-tools contain the commands to compile and package an Android application. The Build-tools are versioned so you can specify what version of the tools you want to use right inside your gradle build script. No more broken builds because you updated your Android SDK.
Another addition is the support for ProGuard. Obfuscating your code is now part of the build tasks.
Android Library Dependencies
Since hardly any app is an island of solitude you will want to use external libraries to help you with common tasks. An Android library project allows you to do just that. But keeping external dependencies in your ide is cumbersome and obtaining your dependencies from maven is much more elegant. With the aid of the m2e and android-m2e Eclipse plugins this also works reasonably well in Eclipse. Where this approach falls short is when consuming Android libraries via maven. Maven packages those artifacts into “apklibs”. They can be consumed when “mvn install”ing your app without a problem but inside eclipse the apklib format is not supported. This leads to the problem that you have to keep the source project in the ide as well.
In a gradle build, dependencies can be both local files or maven/ivy artifacts. The gradle build introduces a new packaging format for Android library projects called the Android Archive (.aar). This format is pretty new (imo not fully finalized) and not widely adopted yet. While the .aar is the future, the maven apklib is the present and this leads to the following problem: The gradle build does not support the apklib format. So for now you can not consume any Android libraries from maven central in your gradle build. Regular java jar dependencies can be consumed without a problem.
Another problem that has not been solved in the gradle build yet is the ability to consume libraries from the Android SDK. The Android SDK ships with many useful libraries from Google like the support-library, admob, analytics, play services etc. Several of these artifacts ship as Android Library projects that can only be consumed in a gradle build when copying the entire project with source. When using maven, one can use the maven-android-sdk-deployer to copy these resources into the local maven repository but no such thing exists for gradle. The solution that Google is planning to implement is to upload these artifacts to maven central in the .aar format. Thereby they can easily be consumed by a gradle build. Why this hasn’t happened yet is hard to say. Maybe because the .aar format is not finalized? Or maybe Google has other priorities?
[UPDATE] As of 30.05.2013, the support library and the google services are bundled in the Android SDK as .aar maven dependencies. They can be easily consumed within your gradle build script like any other maven dependency.
Google I/O 2013 brought a lot of new stuff into the Android development landscape. Surely the Android Studio is the star of the show but at the end of the day the gradle build is more important. It provides the underpinnings to unify the Android development story. In that regards one important feature of the gradle build story is still missing: Google has to publish the core components of the Android SDK to maven central as .aar archives. This will be a strong signal for other libraries to also publish as .aar archives. Until that happens the gradle build will remain a patchwork project.
The Android Studio is an impressive new part of the Android development story – many people had been asking for IntelliJ support. The multitude of features that already go beyond what Eclipse/ADT offers makes for some exciting prospects. At version 0.1 it is very early to adopt it fully for existing larger projects but for smaller endeavours it feels very usable. Google plans to push weekly updates of the Android Studio so glitches will get ironed out pretty quickly. Where does that leave Eclipse/ADT? Google has committed to maintaining both development platforms in parallel but it remains to be seen how long that promise keeps up. At least the gradle build support will be integrated soonish.