I’m sure that when you trays automated dependency management and application building/deploying you will never want to abandon this kind of comfort that it gives. The same situation is with dependency injection; when you will get it ideas. In “normal” desktop, web, or server side project’s integrating with such tools like maven and guice isn’t that complicated like in Android projects.
Android tooling is very consistent and the ADT plug-in isn’t integrated with maven. This isn’t a problem when application is relatively small, or when you don’t want to use continuous integration tools like Hudson. But when you enter Android world from “enterprise” web application like I do, you surely would like to use CI, DI and lots more of cool stuff that was available before.
In this post I’ll present simple Android application that will have Maven and Guice support.
1. Eclipse, Android and Maven
I assume that you already have installed and configured ADT and m2eclipse plugins. To have it working properly we need to install m2eclipse-android-integration from theirs update site:
http://m2eclipse-android-integration.googlecode.com/svn/trunk/com.byluroid.eclipse.maven.android.update/ |
2. Create a simple android project
Using Android project creator create new project and create a pom.xml file and configure maven-android-plugin. Here is a sample minimal pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.luksza.android</groupId> <artifactId>exampleapplication</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>apk</packaging> <name>ExampleApplication</name> <dependencies> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <version>1.5_r3</version> </dependency> </dependencies> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>maven-android-plugin</artifactId> <version>2.6.0</version> <configuration> <sdk> <path>${path-to-android-sdk}</path> <platform>3</platform> </sdk> </configuration> <extensions>true</extensions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project> |
Remember replace ${path-to-android-sdk} with proper path. After that there are only two things that should to be done. From project context menu and select “Maven” -> “Enabled dependency management” and secondly “Maven” -> “Update project configuration” and remove standard JRE library from project build path.
That was quite simple isn’t it? There is one additional thing worth to notice, if yours application would be using Google Maps API you should use project maven-android-sdk-deployer to automatically install proper jar’s in local m2 repository. Whole installation process is described in README.markdown file.
3. Android and Guice
Now when we have enabled dependency management we can add some dependencies ;). First of all we will need Guice 2.0 without AOP (we cannot use Aspect Oriented Programming on Android). Because this jar isn’t available in any known maven repository we should download it from Guice download site and install it in our local repository:
mvn install:install-file -Dfile=./guice-2.0-no_aop.jar -DgroupId=com.google.inject\ -DartifactId=guice-no_aop -Dversion=2.0 -Dpackaging=jar -DgeneratePom=true |
after that we can add new dependency to ours pom.xml
<dependency> <groupId>com.google.inject</groupId> <artifactId>guice-no_aop</artifactId> <version>2.0</version> </dependency> |
Theoretically we can use Guice without any addons … but using Roboguice we can achieve lots more than simple dependency injection eg. using @InjectView and @InjectResource we can easily inject views and resources without casts. Also there are preconfigured Guice modules that have configured standard bindings. To add Roboguice into ours project first we should define new repository from with it will be donloaded
<repositories> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> </repository> </repositories> |
Secondly the dependency should be also added
<dependency> <groupId>roboguice</groupId> <artifactId>roboguice</artifactId> <version>1.1-SNAPSHOT</version> </dependency> |
To have everything working we should create new class eg. ExampleApplication that will extend roboguice.application.RoboApplication
package org.luksza.android; import roboguice.application.RoboApplication; public class ExampleApplication extends RoboApplication { @Override protected void addApplicationModules(List<Module> modules) { } } |
In method addApplicationModules we can add any module that extends com.google.inject.Module. In our example we don’t need to add any extra module. Next we should edit AndroidManifest.xml file and change line
<application android:icon="@drawable/icon" android:label="@string/app_name"> |
into
<application android:icon="@drawable/icon" android:label="@string/app_name" android:name=".ExampleApplication"> |
If we would like to benefit from @InjectView or @InjectResource annotation our activity class should extends roboguice.activity.RoboActivity instead of android.app.Activity. It is very important to notice that any injection can occur after setContentView() method is called. Therefor we cannot inject main activity layout! Here is an example ExampleActivity class that have injected button:
package org.luksza.android; import roboguice.activity.RoboActivity; import roboguice.inject.InjectView; import android.os.Bundle; import android.widget.Button; public class ExampleActivity extends RoboActivity { @InjectView(R.id.Button) Button button; /** Called when the activity is first created. */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button.setText("Injected button"); } } |
That is all I want to share with you. I’ve hope that this information would be useful for you 😉
Pingback: Tweets that mention Dariusz [LocK] Łuksza » Android, Eclipse, Maven and (Robo)Guice together? -- Topsy.com
Hey Ricardo here, one of the original authors of the m2eclipse-android-integration plugin. Nice article, so simple, it puts the “Getting Started” wiki page I wrote to shame:
https://code.google.com/a/eclipselabs.org/p/m2eclipse-android-integration/wiki/GettingStarted
Also thanks for the mention. Hoping to get a new version of the plugin out soon that smooths over some of the rough edges of the original.
Thank you, I’ve done my best to describe it as simple as it is possible 😉
btw. Thanks for kudo 😉
No worries.
BTW could I copy some of your article here to update my “Getting Started” wiki page please? It needs a re-write and your descriptions are very simple and clear.
@Ricardo
Of course you can use it, feel free to redistribute it 😉
Just a quick note: you’re not adding the guice dependency with it’s classifier (no_aop):
mvn install:install-file -Dfile=./guice-2.0-no_aop.jar -DgroupId=com.google.inject -DartifactId=guice -Dversion=2.0 -Dpackaging=jar -DgeneratePom=true -Dclassifier=no_aop
@Ricardo
Thank you Ricardo for this hint.
I’ve already updated it 😉
RIght now it is possible to add dependency to guice with specified version as 2.0-no_aop