Android, Gradle & IDE Integration

by Алекс Руис on June 4, 2013

In this post I’m describing how we use the new “custom model” feature, introduced in Gradle 1.6, to provide IDE integration for Android projects that use the new Gradle-based build system. This feature was designed to allow Gradle plug-in developers provide a custom representation of a Gradle project through the Gradle’s Tooling API.

This post is intended to be a “note to self,” to have it handy once we start implementing Gradle support for Android projects in the Android Development Tools for Eclipse (ADT.)

Background

Android has a new Gradle-based build system that makes it easier to accomplish tasks that were previously hard or impossible to do. We want build.gradle files to be the one and only source of truth. This means that building from the command line, an IDE or a continuous-integration server should always result in the same output.

Before Gradle 1.6, Gradle integration with Java IDEs (Eclipse & IDEA) was been taken care of by Gradle’s tooling API: it provided (and still provides) a IDE-specific representation of a Gradle project that was good enough for regular Java projects. Android’s Gradle plug-in contains a rich set of project-related information that is needed for IDE integration, but also Android-specific data (e.g. additional source folders, resource folders, etc.) Unfortunately, the pre-Gradle-1.6 tooling API model did not allow us to pass that information to IDEs.

To help us achieve our goal, the Gradle folks implemented the changes we needed. The custom model mechanism was released in Gradle 1.6. Thanks, guys!

Android’s Gradle Model

Instead of creating IDE-specific Android/Gradle models, we decided to have an IDE-agnostic representation of a Gradle project. This way, we have a single source of information that is easier to maintain. IDE integration will be implemented as a plug-in for each supported IDE (in our case, Eclipse and IDEA.) The main benefit of this approach is that we can release the Gradle plug-in independently of the IDE integration plug-ins. For example, we can ship a new version of the Eclipse plug-in that has several bug fixes, without affecting the Gradle side of Android.

The Android Gradle model is a rich and detailed representation of an Android project. The core of it is the concept of build variants. A build variant is a combination of build type (e.g. “debug” vs. “release”) and an application flavor (e.g. “free” vs. “paid”.) Of course, this is a very high-level explanation. To learn more about build variants, please read the Android Gradle build system docs.

Build variants are important for IDE integration because each build variant has its own project structure. For example, a build variant has its own output file (.aar file) and its own set of generated source directories. To set up an IDE project we need to know all the source folders, dependencies and outputs of the selected variant in an Android project.

IDE Integration

On one hand, build variants are a powerful concept that makes it easy to create multiple types of the same application. On the other hand, this new concept pushes the limits of what an IDE can do. IDEs were not designed to handle multiple versions of a same project (not their fault: probably this is the first time that such thing exists!) To properly use build variants in an IDE, some fundamental changes need to be made.

  • Display all variants and allow user to select the variant to work on.
    This is not really a “fundamental” change. An IDE needs to show all the available variants, the selected variant and allow the user to select a different variant to work on. In Android Studio we implemented this as a “Build Variants” tool window:
  • React to changes in build variant selection.
    As difficult as it is to implement this feature, it is not a fundamental change either. Once the user selects a different build variant, the IDE needs to react accordingly:

    1. adjust source directories: only mark as “source” the directories specified by the selected build variant
    2. adjust dependencies to other projects or 3rd. party libraries
    3. opened editors need to show contents that are relevant to the selected build variant
    4. point to the correct output file (.aar file) for launching and debugging
    5. trigger a project build

    All of this have to be done correctly and, of course, pronto.

  • Refactoring.
    This is where all the fundamental changes need to happen. Even though we haven’t fully explored the scope of changes in refactoring that build variants need, we have some ideas.

    Take class renaming for example. Let’s say we have class com.example.Class1 in the project’s default configuration (i.e. the code that doesn’t change regardless of the selected build variant.) Our sample project has 2 build variants and each have their own version of class com.example.Class2. Both versions of Class2 have a reference to Class1 (let’s say has a field of type Class1.)


    What should happen if I rename Class1 to MyClass?

    Yep, both versions of Class2 need to be included in the rename refactoring. The problem is that the IDE only knows about one Class: the one that comes from the selected variant. The IDE has no notion of all the other versions of that class. To make this refactoring work we need to let the IDE know about all the possible versions of a class or resource. That could mean making changes to how an IDE indexes files. This is a lot more complex than it sounds. I’m sure this is just the tip of the iceberg.

    May the force be with us.

Other simpler (but equally important) features that IDE integration should include are:

  • Create Grade-based Android projects
  • Import existing Gradle-based Android projects
  • Automatically detect changes in Gradle files and update the IDE project structure accordingly
  • Use Gradle as the only mechanism for building

Conclusion

The new Android Gradle build system is one of the best additions to an Android app developer’s toolbox. It makes it a lot easier to create different versions of the same app (not an uncommon use case.) IDE integration with the new build system is crucial, but not trivial to implement.

In this post I shared some ideas of what needs to be done to make it happen. Some of the points discussed in this post are already implemented in Android Studio. By the time you read this post, we should have started work on Eclipse support.

{ 11 comments }

Android Studio: our new, shiny Android IDE

by Алекс Руис on May 16, 2013

The cat is out of the bag: yesterday, during Google I/O‘s keynote, we announced our new IntelliJ IDEA-based Android IDE, Android Studio. This is what my team has been working on for the past months.

From what I read on the web, Android Studio has been pretty well received. I personally heard nice comments about it, from “awesome!” to “fantastic!” and “really cool.”

Here are some highlights about Android Studio. I’ll be writing more detailed blogs about our IDE soon. Before I continue, let me make this clear:

This is a personal blog. The opinions expressed here represent my own and not those of my employer, Google.

With that out of the way, here we go:

Our goal is to be Gradle-centric

We are working closely with the Gradleware folks on a new Gradle-based build system. Right now, with Android Studio, you can create new Gradle-based Android projects or import existing ones. When you build your project in Android Studio, we disable the default IDEA Java builders and delegate the build to Gradle. You get the same output from building within Android Studio or from the command line. Our goal is to have Gradle build files as the only source of truth.

This is an early access preview

Even though it is possible to create applications with Android Studio, there are still rough corners, bugs and features that we have not implemented yet. It would be great to get as many bug reports and feature requests from early adopters. Here is the list of known issues.

We still support Eclipse

We will be supporting Eclipse ADT as well. In fact, we plan to add similar Gradle support to ADT. The catch here is that given limitations in Eclipse, especially JDT, we cannot guarantee a development experience as smooth as Android Studio. You can, however, export your Eclipse-based Android project as a Gradle project, and then import it into Android Studio.

This is not a fork of IntelliJ IDEA

We have been working, and continue to work, really close with JetBrains, the folks behind the best Java IDE, IDEA. They implemented the changes we needed in their platform in order to develop Android Studio. Eventually, you will be able drop Android Studio as a plug-in into your copy of IDEA.

That’s it for now. Stay tuned for more Android Studio posts :)

Update: Xav‘s and Tor‘s Google I/O talk “What’s New in Android Developer Tools” is on YouTube!

{ 29 comments }

Joining the Android project at Google

February 25, 2013

I’m most excited to announce my new adventure! Today is my first day as part of the Android project at Google. In particular, I’ll be working on tooling for Android. For the past 2 years I worked in the Eclipse tooling team (also at Google.) I had the privilege to work with an amazing group [...]

Read the full article →

Interviewing with Google? Read this!

November 19, 2012

In response to my post, “My team at Google is hiring,” I got a lot more résumés than I expected. This is absolutely great! Many thanks to all the folks interested in working in my team! While chatting with a few of the potential candidates, I offered some advice on interviewing with Google. This is [...]

Read the full article →

Weekend Project: Thread Dump Viewer for Eclipse

November 5, 2012

A couple of weeks ago, one of our users reported that Eclipse consistently froze when executing some action. I was hoping that Eclipse would have an editor where I can open the thread dump I got and navigate, through hyperlinks, from stack traces to source code. The closest thing I found was the “Java Stack [...]

Read the full article →

Fluent interfaces: don’t chain for the sake of chaining

September 18, 2012

One of the goals of FEST-Assert 2.0 is to learn from the mistakes we made in the 1.x releases, even if that means not being backwards-compatible. Not fully understanding the semantics of the API we were building, is, IMHO, one of the biggest mistakes we made in FEST 1.x. We were not able to see [...]

Read the full article →

My team at Google is hiring

September 13, 2012

This is a follow up for a tweet I sent this morning. I’m sharing some more details to save everybody’s time. In short: my team at Google is hiring. If you enjoy writing Eclipse plug-ins, send me your résumé at: alruiz at google.com. Important details: No prior experience with Eclipse is needed. We are looking [...]

Read the full article →

FEST named finalist In ATI Automation Honors

September 10, 2012

I’m pretty happy to announce that FEST has been named a finalist in the 4th Annual ATI Automation Honors. The winner will be announced at the TestKIT 2012 Conference. If you are happy FEST user, please vote for us! :) Update: FEST’s home page was down, most likely due to the recent problems GoDaddy is [...]

Read the full article →

Never, ever use Iterable as a return type

September 6, 2012

This is a short rant. Please do not use Iterable as a return type. Its Javadoc states that Implementing this interface allows an object to be the target of the “foreach” statement. That’s the only purpose of this interface. Other than that, this interface is almost useless, or at least a PITA to consume. For [...]

Read the full article →

A handy setup for writing articles for developerWorks, using Eclipse

August 22, 2012

Today, IBM developerWorks published the article I recently wrote, “Integrate an external code checker into Eclipse CDT.” When writing for developerWorks, we have the option to write in three formats: Word, Write or XML. Since I find it pretty painful to use Word or Write, I usually choose the XML format. developerWorks provides a pretty [...]

Read the full article →