Monday, November 14, 2011

Roboinstaller: Install roboguice dependencies in your device

Yesterday I wrote about a crazy idea of installing your application dependencies in the device to make the builds faster. This is just an example of what's possible.

After yesterday's idea I decided to give it a try and install in my rooted nexus one all the roboguice dependencies to see if my build times improved. To test it out I Manfred Moser's roboguice sample code called: roboguice-calculator.

Mike: I was going to test with the Astroboy roboguice's demo, but I didn't feel like dealing with hg. Plz move roboguice to git :)

To do this I have separated the whole process in steps.

Pre-dexing step

First of all, you need to get a pre-dexed jar files of all the dependencies. You can pre-dex your jar files with the following line:

dx -JXmx1024M -JXms1024M -JXss4M --no-optimize --debug --dex --output=./my_dep_dex.jar my_dep.jar

Creating the permissions XMLs
Once you get all your dependencies pre-dexed, you need to create the permissions XMLs which looks like this:

<permissions>
<library name="my.dependency"
file="/data/data/com.nasatrainedmonkeys.roboinstaller/files/my_dependency_dex.jar" />
</permissions>

Installing the dependencies
After some hacking to the scala-android-libs src code I had the code ready to install dependencies on the device.

Modifying the AndroidManifest
Inside the tag you need to add all your dependencies with the <uses-library> tag. It should look like this:

<uses-library name="my.dependency"/>

Modifying the pom.xml
The last step is setting the scope to provided using provided tag.

Results
Building the ordinary app: Total time: 22.212s

With this hack: Total time: 10.431s

Issues
Since mvn doesn't create a jar file with all the dependencies inside, I failed on my first try because the guice dependency needed the javax.inject jar file. I guess there should be a way to create a "fat-jar" with every dependency inside. If that's possible pre-dexing a dependency would be much more easier.

Future work
This has shown the approach is totally useful. Next step is to create an android app that can install pre-dexed files and create the xml without needing to recompile the whole application. This approach would also take me to separate my application into different libraries to develop as fast as possible :)

Source code
I have placed the installer code and the sample application with the modifications in this github repo: Roboinstaller

3 comments:

  1. Awesome work! This will be incredibly useful.

    Now I need to write an SBT plugin to add and remove those AndroidManifest lines depending on if I'm building for the market or not...

    Also, the AndroidManifest part you mention seems like it is getting eaten by the browser because of the angle brackets.

    ReplyDelete
  2. @James: Thanks! I just fixed it.

    ReplyDelete
  3. You should be able to run `maven assembly:jar-with-dependencies` to get a single jar

    ReplyDelete