Android360: Cool Stuff

Spring vs. RoboGuice: Dependency Injection für Android

Lars Röwekamp und Arne Limburg

In der neuen Kolumne „Cool Stuff“ wollen wir in regelmäßigen Abständen ein wenig über den Tellerrand blicken und Cool Stuff jenseits des Android SDKs vorstellen. Den Anfang macht das Thema „Dependency Injection für Android“.

Android360

Der Artikel „Spring vs. RoboGuice“ von Lars Röwekamp und Arne Limburg ist erstmalig erschienen im Android360-Magazin 1.2012.

http://android360.de/

Wenn Sie nicht gerade aus der Java-Steinzeit kommen, gehört Dependency Injection wahrscheinlich mittlerweile zu Ihrem täglichen Handwerkszeug. Egal ob standardisiert via JSR 299 und JSR 330 oder proprietär via Spring, Google Guice oder eines der vielen anderen DI-Frameworks – einmal genutzt, möchte man das Inversion-of-Control-Pattern keinesfalls mehr missen. Was ist aber, wenn man aus der Welt des Mobile Java Development kommt? Muss man dann automatisch auf die Vorzüge dieses Konzepts verzichten? Das Android SDK zumindest bietet hier erst einmal keine Unterstützung. Die gute Nachricht ist, dass es auch im Umfeld von Android die eine oder andere brauchbare Lösung gibt. Die schlechte Nachricht ist, dass Sie, wie so oft in Java, die Qual der Wahl haben. Aber seien wir einmal ehrlich, es gibt Schlimmeres.

Der „Old School“-Ansatz

Da es sich bei Android bekannterweise um Java handelt (oder auch nicht, wenn es nach Google geht), spricht zunächst einmal nichts dagegen, auf bewährte Kräfte aus der Java-SE-Welt zu setzen. So ist es theoretisch, und die Betonung liegt hier auf „theoretisch“, durchaus möglich, Spring oder Google Guice direkt als DI-Framework der Wahl zu verwenden. Dagegen spricht natürlich einerseits die Größe dieser Frameworks. Spring in der aktuellen Version 3.1 zum Beispiel hat selbst in der kleinsten Variante (core, beans und context) einen Overhead von 1,77 Megabyte. Für eine mobile Anwendung ist das deutlich zuviel. Und auch Google Guice ist nicht gerade ein Leichtgewicht im Hinblick auf ein Mobile Device. Das zweite Problem ist, dass diese Frameworks in der Regel Java APIs verwenden, die in dem (abgespeckten) Java von Android gar nicht enthalten sind. Wie sieht also die Alternative aus? Viele der Non-mobile-DI-Framework-Anbieter haben mittlerweile auch eine mobile Variante mit entsprechend kleinerem Footprint im Angebot. Hinzu kommt noch das eine oder andere Framework, das bestehende Konzepte der „großen Brüder“ in die mobile Welt adaptiert.

Der „Mobile“-Ansatz

Einmal abgesehen vom neuen DI-Standard via JSR 330 und JSR 299, ist Spring wahrscheinlich das erfolgreichste DI-Framework. Was liegt also näher, als mit der Betrachtung der beiden mobilen Spring-Derivate Spring ME und TinySpring zu starten? Das Framework Spring ME [1] existiert bereits seit 2008 und wurde ursprünglich entwickelt, um Java ME mit Spring-Features zu versorgen, ohne dabei das Spring Framework selbst zur Laufzeit zu benötigen. Das wäre auch gar nicht möglich, da Springs Dependency Injection stark auf Runtime Reflection baut. Das ist ein Konzept, das wir unter JavaME vergeblich suchen. Spring ME dagegen setzt auf Buildtime-Analysen und Code Generation. Das bedeutet, dass die BeanFactory nicht zur Laufzeit aufgebaut, sondern zur Buildtime via mvn spring-me:generate erzeugt wird. Der große Vorteil sind zero Kilobytes Runtime Overhead für das Framework. That’s it. Die Spring-Konfiguration sieht übrigens mehr oder minder genauso aus, wie man es von den XML-basierten Spring-Konfigurationen gewohnt ist. Erlaubt sind unter anderem Property-based Injection, Constructor-based Injection, Injection von Listen, Primitiven, anonymen Beans, Lazy- und Eager-Initialisierung etc.

Einen etwas anderen Ansatz verfolgt das Projekt Tiny Spring [2]. Es versucht, Teile des Spring Frameworks auf der Android-Plattform zu emulieren. Tiny Spring richtet sich vor allem an diejenigen, die ihren Spring-basierten Code auf mehreren Plattformen, unter anderem eben auch auf Android, laufen lassen wollen. Zitat der Tiny-Spring-Webpage: „This project is for people that love Spring and want to carry existing code to the Android platform“. Der Funktionsumfang des noch jungen Projekts hält sich in dem aktuellen Release 1.0.1 noch in sehr bescheidenen Grenzen. Entsprechend dünn ist auch die vorhandene Dokumentation. Trotzdem sollte man das Framework im Auge behalten.

Die beiden bisher vorgestellten Varianten setzen auf den Ideen von Spring und den von dort bekannten, XML-basierten Konfigurationen auf. Einen anderen Weg geht das Framework AndroidAnnotations [3]. Wie es der Name schon vermuten lässt, bietet AndroidAnnotations eine Reihe von nützlichen Annotationen an, die das tägliche Leben eines Android-Entwicklers deutlich erleichtern können. Möglich wird das durch einen zusätzlichen Compile-Schritt, der automatisch hinzugefügt wird und mithilfe des Java Annotation Processing Tools Sourcecode erzeugt. Auch hier wird also generierter Code genutzt, was aufgrund der limitierten Reflection-Performance unter Android sicherlich nicht die schlechteste Wahl ist. Auch AndroidAnnotations verfolgt eine, wenn auch aus Robert C. Martins Clean Code entliehene Philosophie: „The ratio of time spent reading versus writing is well over 10 to 1, [therefore] making it easy to read makes it easier to write". Das nur knapp 50 Kilobyte große Framework bietet neben Dependency Injection für Views, Systemservices, Resources und Custom-Objekte unter anderem auch Annotationen für ein vereinfachtes Threading-Modell (UI Thread vs. Background Thread), Event Binding (nie wieder anonyme Listener!) und REST-Funktionalität. Auf den ersten Blick macht das ebenfalls noch recht junge Framework einen guten Eindruck und überzeugt im Gegensatz zu den bisher betrachteten Mitbewerbern durch eine gute Dokumentation, eine relativ aktive Entwicklercommunity und durch die eine oder andere Android-App im Android Market, die dieses Framework nutzt.

Interessant könnte zukünftig auch ein Projektvorhaben aus dem Weld-Umfeld werden. Ziel dieses Projekts scheint es zu sein, den CDI-Standard oder zumindest Teile davon auf die Android-Plattform zu portieren. Da es sich bisher aber nur um ein Vorhaben handelt [4] und scheinbar noch nicht einmal ein Team existiert, ist davon auszugehen, dass wir auf die Realisierung noch einige Zeit warten dürfen. Last but not least wollen wir uns noch ein Framework anschauen, dessen Committer-Aktivität sehr hoch ist und das unserer Meinung nach aktuell das vielversprechendste DI-Framework im Android-Umfeld ist: RoboGuice.

Geschrieben von
Lars Röwekamp und Arne Limburg
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.