2010-11-26T17:52:00CET
[IntelliJ, Maven, Android]
Christian Bauer

I've just upgraded to the latest IntelliJ IDEA 10 preview to check if Android support has improved. One particular issue I had for the last half year was that the Maven features of IntelliJ had no support at all for an Android project facet. Or vice versa; the result was that developing an Android application with Maven and IntelliJ was a huge pain. This is my bug report with Jetbrains that finally triggered some changes and it should be a usable combination now.

There is no documentation how you best start an Android project with Maven and IntelliJ, so I thought I'd write down how I got it working to save you a few hours.

First create a regular Android Maven project, either following these steps or better download my HelloWorld project skeleton. I've already cleaned up the project root directory and moved the Android resources/overlays/whatever into the standard Maven project layout under /src/main/android and configured this in the pom.xml.

Check the pom.xml and also set the ANDROID_HOME environment variable (if you haven't already during your SDK install), so you can call Maven from the commandline. You should now already be able to build and package the project using mvn clean package. Don't continue if this fails, try to get the Android & Maven combination working first without the IDE.

Start IntelliJ and create a new project:

AndroidMavenIntellij_Screenshot01

Pick your project root directory next and you can also enable automatic import of Maven projects so changes to your pom.xml will be automatically detected by IntelliJ.

If you are now trying to compile in IntelliJ with Build > Make Project, you will hit the first problem: "Package R does not exist":

AndroidMavenIntellij_Screenshot02

(Rant: All of this is so complex because the Google clowns decided that they need a code generator in the build lifecycle of an Android application. The reasoning is that it is soooo much better to write GUI code in XML files, without a schema, compared to plain type-safe, auto-completed, easily compilable Java. And no, you are too stupid for setContentView("myLayoutKey"), it has to be setContentView(R.generated.code). Yes, all of the build and packaging is so complicated because the average developer can't type a string correctly and oh no! it would be a runtime error if you don't! We can't have that, everyone has to suffer, on every compile run. If it would be a string, regular javac and some post-compile packaging would be good enough to build a deployable Android app, no code generator needed. Look at this diagram of the build process, do you realize how much simpler this would be without the crap at the top right? This is by far the most annoying thing about Android and I almost stopped learning it when I saw this diagram for the first time.)

The problem is that IntelliJ is supposed to run the code generator that produces R.java whenever you change any of the XML files. I could never get it to do that, no matter what files I edited or buttons I clicked. Luckily the IntelliJ programmers knew this, they added a setting that (I'm guessing) runs a Maven goal to generate R.java, you just have to enable it by selecting "Copy resources from Maven artifacts before Make", disabling the built-in AAPT generator:

AndroidMavenIntellij_Screenshot03

(What does "Copy from Maven artifacts' mean? Should this be 'Running a Maven goal'? Also, it's not a compiler, it only generates a single R.java file with hilarious pointers!)

After that change the "missing import" went away and I could build the project with IntelliJ. Too bad I now have to wait a few seconds on every compile run for the code generator but developer time obviously is cheap.

If you want to execute Maven goals of your project from within IntelliJ you have to set the SDK environment variable in the Maven Runner settings:

AndroidMavenIntellij_Screenshot04

Finally, this is a Run Configuration that will build and deploy your application on a device or emulator:

AndroidMavenIntellij_Screenshot05

Some of these issues can probably be fixed for the IntelliJ 10 final release. Next on my list are testing and remote debugging, let's see if that works out of the box at least.

Update (29.11.2010):

Although my setup works with a Maven-generated R.java, waiting for the Maven background process on every compile is quite annoying. Furthermore, although a Make of the project in the IDE works now, I'm still sporadically seeing the R class missing in source code (red font, as shown above in the source). My next attempt is to fix the source paths of the project:

AndroidMavenIntellij_Screenshot06

I've included the target/generated-sources/r as a regular source directory in the module. So far this seems to fix the problem and I get the green light on my source and Make works as well. Of course now IntelliJ consumes 100% CPU immediately and forever when I open my project, but this is probably another new bug in build 98.402. Grrrrrrr....

The bug report with Jetbrains is being tracked here.

Update (02.12.2010):

Just upgraded to the latest build of IDEA 10, 98.486. This fixes the generated sources path and you can now download my HelloWorld Maven skeleton, create a new project with an "external model" and everything builds and deploys fine. The only thing was that the Logcat window wouldn't be available immediately, I had to close and reopen the new project once for the tab to become visible.

My next problem is attaching Android "Javadoc" to the project module, so I can lookup the API documentation. I've tried attaching $ANDROID_HOME/doc/reference/ but so far no luck.

8 Comments
2011-03-23T18:23:47CET
Rick Herrick
Great post, Christian, I've taken your template and am working with it now. Have you thought about creating a Maven archetype from that template? One other note, using your template out of the box, I ended up with a warning (well, it was [INFO], but still): [INFO] THIS TOOL IS DEPRECATED. See --help for more information. [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ This is caused by a change in how the ApkBuilder class is called and is easily fixed by bumping up the maven-android-plugin version. I set it to the latest, which is 2.9.0-beta-2, but the latest release version is 2.8.4. You can find the available versions on Maven Central: http://repo2.maven.org/maven2/com/jayway/maven/plugins/android/generation2/maven-android-plugin/
2011-03-24T01:10:17CET
Christian Bauer
I'm not a big fan of Maven archetypes, I think it's better to understand what a build does and part of that is setting it up from scratch without extras. Also, whenever I've tried an archetype it was outdated and didn't generate anything useful. Point in case, they changed again how IntelliJ 10.x handles the idiotic Android code generator, so what I wrote is probably already wrong.
2012-02-04T14:08:22CET
Vegard
Hi. It's been a while since you wrote this and I'm guessing you've figured out how to attach the JavaDoc to the project, but in case other people wonder, here's how I did it in IntelliJ 11: * Make sure the documentation is downloaded through the Android SDK Manager. * Open the Project Structure dialog in IntelliJ. * Select "Libraries" from the left hand side list. * Select "Maven: com.google.android:android:SOME_VERSION" from the list of libraries that appears. * If any JavaDocs are already attached, detach them. * Attach the JavaDocs from where they have been downloaded, in my case C:\Program Files (x86)\Android\android-sdk\docs\reference
2012-03-24T05:19:47CET
Dale King
Regarding your rant about about the code generation for UI IDs, I, for one, am grateful for this, because it means code completion works for entering the IDs. No, I don't want to have to get string values exactly correct only to find out at run time that I got it wrong. Note also that converting the names to an integer ID at compile time is more efficient.
2012-03-26T17:31:26CEST
Christian Bauer
You completely missed the point of my rant. The issue is that someone thought that writing lines of XML is better than writing lines of Java, without even providing a schema (the equivalent of an API in Java). That this XML is then piped through a mandatory code generator is just icing on the pile of horseshit that is Android.
2012-12-30T09:05:59CET
Ben
I'm trying to use Maven on a project, but have already built part of the Android project using the latest IntelliJ. Unfortunately I don't feel like I can find a straight forward step by step guide on how to set this up. Is it really this much of a pain? I downloaded the HelloWorld app here and imported it. It failed to run for me :-\
2013-01-30T14:57:07CET
Romain Piel
Very cool, thanks for this great blog post! As I'm a github addict, I've added your starter project to a new git repo. I've linked the README to your blog post. Thanks again.
2013-03-27T16:50:32CET
Stan
Thank you for the great tutorial. Time goes on, and there are some fixes should be done to the pom.xml. If you get an error while building the target with something like that: android-sdks/platforms/android-8/tools/aapt: No such file or directory than you are using an old version of the Maven Android plugin. Change the following lines in the pom.xml: <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>maven-android-plugin</artifactId> <version>2.6.0</version> to these (artifactId and version are changed): <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId> <version>3.5.1</version>
Add comment

Creative Commons License