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.

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:

adjust source directories: only mark as “source” the directories specified by the selected build variant

adjust dependencies to other projects or 3rd. party libraries

opened editors need to show contents that are relevant to the selected build variant

point to the correct output file (.aar file) for launching and debugging

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:

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.

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!

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 advice that was passed to me when I interviewed a couple of years ago. Even though these tips are nothing out of ordinary, they are, however, practical and useful. Since I found myself repeating them over an over, I thought it may be a good idea to write them down.

Here we go.

1. Listen to your best friend: the (Google) recruiter

Is the recruiter’s job to get you an offer from Google. He or she will do everything in their control to help you. As part of their job, they will tell you what you need to study for the interview. It is a lot of material, but it is absolutely worth the effort. Needless to say, Google is awesome.

2. You decide when to interview

It is your decision when to interview. Take all the time you need to prepare and don’t let anybody push you. Knowing when you are ready is difficult though. Studying all the material is pretty much impossible. Instead, you need to set a realistic goal. In my case, since I was terrified by the interview process, my goal was to cover the basic algorithms and data structures, and study until I feel calm and confident.

3. Practice, practice, practice…and get a whiteboard

It does not matter if your solution is wonderful, you are in trouble if the interviewer cannot understand it. While preparing for the interview, solve problems on a whiteboard. Learn how to express your ideas and write code (yes, write code on a whiteboard) in a clear, neat and organized way. You want interviewers to understand your solutions.

4. Let all your friends at Google know that you are interviewing

The more Googlers that can say something good about you, the better. You may be able to skip the phone interview (it is not a promise though.) I personally hate technical phone interviews.

5. $hit can happen

Preparing for the interview does not guarantee you will pass it. There are many factors that can work either in your favor or against you. Plus, there is no such a thing as a perfect interview process. $hit out of your control can happen. Don’t feel too bad if, for whatever reason, you fail the interview. It happens more often than you think. Seriously. Just learn from the experience and apply again in six months. Like I mentioned earlier, working for Google is worth the effort.

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 Trace Console,” which provides hyperlinking to source code. It would have been nice if there is a specialized editor that provides the following features, besides code navigation:

an Outline View that shows the threads by name (with icons representing their state) and any deadlocks found

some basic syntax highlighting to make reading easier

ability to collapse blocks (e.g. a thread or stack trace) to minimize noise

navigation to thread definitions from references (e.g. a deadlock)

BTW, IntelliJ IDEA provides something somehow close to what I’m asking for since 2008! 2008!

In addition, I didn’t want a tool that analises a thread dump for me (e.g. TDA or the IBM one.) So far, I haven’t seen a thread dump that is that hard to read.

Of course I had to scratch my own itch! This past weekend I finally had time to write my own “Thread Dump Viewer.” It is an editor that provides everything I described. I was able to write a working editor in a matter of hours, using Xtext. The key was getting the grammar right. I spent an additional couple of hours making it “prettier.”

Here is a screenshot of the editor (click to enlarge.)

Here is a demo showing off the features of the “Thread Dump Viewer.”

I created this tool for my own use. I haven’t open-sourced the code or made the plug-in publicly available simply because I don’t know if anybody else would find this tool useful. If you do, please leave a comment.

(10/07/12) Update: I’m in the process of open sourcing this plug-in. I need to do some cleanup (code formatting, add copyright headers, etc.) first. I expect the first version of the plug-in to be what I have now. Right after that, I’ll be implementing the features mentioned in the comments:

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 that each assertion in the method chain should be an independent unit.

To better explain my point of view, consider this snippet using FEST-Reflect‘s API:

This is when it gets confusing. Now a method in the chain affects the behavior of the next one. It is hard to tell if overridingErrorMessage only applies to isInstanceOf, or to all the methods in the chain. It is so confusing that I cannot remember what were the semantics of overridingErrorMessage!

Now it is easier to understand that overridingErrorMessage only affects isInstanceOf.

Looking back, I can see that I introduced overridingErrorMessage the way I did because I naively thought that method chaining makes it easier to write and read code. It surely makes it easier to write code (just press “.” and your IDE’s content assist will show you all the available methods) but I showed you that chaining methods does not always produce a readable API.

In short: I abused method chaining.

Conclusion

When creating a fluent interface using method chaining, step back and think what are you trying to achieve. Do the methods in the chain share a common purpose? Are you chaining a bunch or independent methods? Regardless of the style you choose, be consistent and try not to mix them. That will make the code written with your API readable.

Oh BTW, we made the same mistake (again) in FEST-Assert 2.x. Luckily, there is still time to fix it :)

Return a Collection instead. If your users may need to access to the elements by index, return a List.

(I actually think that Iterable should not even used for parameters, but I’m not 100% sure yet.)

Update: After reading the comments in this post, I realized I didn’t cover one use case: collections that contain a big number of elements and are lazily loaded. I also did not specify the context I was talking about: domain-specific APIs that you are in control of.

I still think that Iterable is a poor choice. Since we are in control of the API we can provide something more useful (or potentially more useful) to the consumers of such API. In the case of lazily-loaded collections, provide something like a Page object. It may or may not implement Iterable. A Page class may contain other useful information besides simple iteration of elements (e.g. the page number.)

Changing the subject a little bit, this is something that I’ve seen quite frequently, all in the name of “flexibility”:

Since we are already dealing with List, why not just return the same type?

Update 2: If you are thinking about Guava‘s usage of Iterable. please read the comments, which includes one from the man himself, Kevin Bourrillion.

Update 3: This is my position about general-purpose libraries like Guava:

Guava’s goal is to make Java easier to use. It provides a lot of useful functionality that IMHO should be in the JDK itself. As such, it needs to deal with very general classes such as Iterable. Plus, it provides utilities to overcome some of Iterable‘s deficiencies (like lack of a isEmpty method.)

My post is about domain-specific APIs that you provide to your users, not something like Guava.
]]>

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 detailed tutorial on how to write an article in XML. In addition, developerWorks provides an “author package” that includes a little command-line program to convert the article in XML format to an HTML page, something handy when you want to see how your article will look like when published.

While writing my last article, I noticed that I was wasting too much time switching between my XML editor (Eclipse), the conversion tool and the browser (I like to review the article as I write it, and the HTML format is a lot easier to read than XML.)

I wanted to write and preview everything using a single tool. Unfortunately, there is no WYSIWYG editor for developerWorks’ XML format. The best I could do is to have everything, the editor, the command-line tool and browser in one place: Eclipse.

On the left side I have the XML editor. Once I’m done writing, I switch to the terminal and run the conversion tool (after the first time I just press “UP” and “ENTER.”) Once conversion is done, I just refresh the browser (on the top-right) to preview the article.

This simple setup saved me a lot of time (I’m using a 30-inch monitor, BTW.) If you write or plan to write articles for developerWorks you may want to give it a try :)

You can find more information about the terminal plug-in at the project’s home page.

What I forgot to mention is that being in an IDE is pretty handy if you include code snippets or a code attachment in your article. In my case, for code snippets, I write code in a Java editor to ensure I’m not writing stuff that doesn’t work. Then I copy/paste code between editors.