Friday, October 15, 2010

Using IntelliJ (or any IDE) with command line tools for developing Android projects

Recently I did some Blackberry development, and started using IntelliJ for that. I liked the concept of having the IDE separate from the build environment. There is some extra work involved but it is convenient if you need a command line interface may be to automate your builds.
Anyways jumping directly into the topic. I have here put together somethings you will need to do to use your choice of IDE and build using android command line tools. Since I have started liking to work with IntelliJ, I will also mention some IntelliJ specific tweaks.

So, clearly there are 2 parts here: The IDE set up and the build setup.
For build set up, we can just use the 'android' command to create the project. So, if we have a project in mind say TestProject, we'll create it using the command :

android create project --target 8 --name TestProject --path ./TestProject --activity TestActivity --package com.foo.Test

You can know the target by issuing the command :
android list target

I will not go deep into what are the targets and why you need them. You can find this information on the Android Developers Website.

The create project command will generate a directory structure which will contain bunch of directories and some configuration files and the build.xml required by ant.

Before you create/import the project in your IDE, issue the "ant debug" command on this generated directory structure. This will generate the R.java file which is the resource file which is needed for compiling along with your source files.

If you come from the Eclipse world, you know that there is a "workspace" in which there can be multiple "projects". Analogous to that, in IntelliJ, there is a "Project" in which there can be multiple "modules".

Talking in terms of IntelliJ, create an empty project (without any modules).
Now,
- Click File -> New Module
- In the Add Module dialog, see that "Create module from scratch" is selected. Click next
- In the Content Root field, browse to the root of this project. The name field will automatically be updated. Click Next
- It will mark the TestProject/src and the TestProject/gen directories as the source directories. This is what we want and this is why we ran the build process before creating the process. If you haven't run the build command before, it will only show the "src" directory. In that case, after you create the project, run the ant command and then come back to the module properties and mark the "gen" folder as a source folder. Doing this is important, or else it will never resolve the R.java references and is quite frustrating.
- Click Next and then Finish.

Now that we have added a new module, we'll need to add android libraries so that we can get intellicense !
- Right click on the module, go to Module Settings.
- Click on dependencies tab.
- Click Add -> Module Libraries
- Click Attach Jar Directories
- Select the specific android platform directory (that you used for creating the project with --target) For us that will be android-8 and will be located at ${ANDROID_SDK}/platforms/android-8
Select this path. Click OK twice. Click Apply.

You are all set !! But wait. There is still a trick pending !
Any time you change any of the resource files, the R.java will be outdated. No issues while building, but the IDE will start cribbing. The Eclipse plugin takes care of updating th R.java. For IntelliJ or other IDEs it might be irritating to see those unresolved references. Not just irritating to see, but some IDEs constantly bug with pop ups for unresolved references. A common mistake will be to import the generic "android.R" package ! In this case, the "R" reference will be resolved but won't find any of user defined resources.

So, each time when you add a resource, you'll need to build by issuing the ant command. But, many times the code is not complete and there is not point running the whole build. All we need is the command to generate the R.java file.

Simple, before writing any code, just run the ant command with the verbose output turned on. E.g. ant -v debug

In the -pre-build target, you will find the command for generating the R.java file. An example is as follows :

-pre-build:

-resource-src:
[echo] Generating R.java / Manifest.java from the resources...
[null] Current OS is Windows 7
[null] Executing 'C:\android-sdk_r07-windows\android-sdk-windows\platforms\android-8\tools\aapt.exe' with arguments:
[null] 'package'
[null] '-f'
[null] '-m'
[null] '-M'
[null] 'C:\androidworkspace\TestProject\AndroidManifest.xml'
[null] '-S'
[null] 'C:\androidworkspace\TestProject\res'
[null] '-I'
[null] 'C:\android-sdk_r07-windows\android-sdk-windows\platforms\android-8\android.jar'
[null] '-J'
[null] 'C:\androidworkspace\TestProject\gen'
[null]
[null] The ' characters around the executable and arguments are
[null] not part of the command.

Now, all you need to do is extract and form command from this and put it in a batch file (or shell script) and whenever you add any resources, just run the batch file in order to generate the R.java

Hope this helps someone !