What are the specific benefits or advantages of using a dependency injection framework for Android, like Dagger, Transfuse or RoboGuice?
For example, what kind of apps would benefit the most from using DI? is there more of a performance advantage, or is it more on the ease of extending an app, or even more about making it testable?
One of the reasons for asking this is to gauge if an app I'm developing would actually benefit from it or not much. Since I intend the app to be serious at some point, testability and ease of extension would be great, even if costly to use (more time to setup, learning curve, etc) for the first versions.
Thanks!
For example, what kind of apps would benefit the most from using DI?
Dependency injection (as a pattern not a library) benefits almost all code.
It promotes designing modular components which expose only the necessary APIs required to perform a specific action. When you are forced to break up pieces of your applications you have to consider how much implementation detail to expose, how the API behaves, and the visibility of classes and methods.
It promotes logical abstractions of components (think: interfaces and their implementations). You certainly don't have to do this, but it ends up occurring organically anyway the more you DI things.
It facilitates testability by creating a single point of type consumption through which a class obtains something it needs. Need to swap out a Foo for a TestFoo? No problem.
Is there more of a performance advantage?
No. The dependency injection libraries exist solely to reduce boilerplate around the pattern and increase the declarative ability to request dependencies.
Is it more on the ease of extending an app?
Absolutely. While I would never recommend using Guice (or RoboGuice) in an Android application, the introductory talk to Guice from Google I/O is a fantastic introduction to why dependency injection is important in this regard.
Even more about making it testable?
Yes and no. This is a happy side-effect of proper abstraction and modularization. Testing is a great thing so the fact that dependency injection offers an ease into it is also great.
I gave a talk about Dagger in the context of Android recently which you can watch* or view the slides. The talk starts out with dependency injection as a pattern and then moves into how Dagger reduces the boilerplate and enables some pretty cool features as well.
I also made a fairly advanced sample application which leverages Dagger for complex injection use-cases that might also be worth checking out.
*The talk is currently not free, but will become so at some point in the next 10 months.
Related
I am currently integrating architecture components into my app according to the official documentation and the sample apps provided by google (sunflower and todo-app). I realized that none of these use interfaces for ViewModels (the sunflower app does not even use interfaces for repositories).
My question is: is it reasonable to just omit the interfaces for ViewModels (including advantages and disadvantages)?
Is it reasonable to just omit the interfaces for ViewModels?
The below is quite general and applicable not just for ViewModels.
Advantages:
less code
Disadvantages:
won't be able to use most of the well-known design patterns;
won't be able to properly unit test classes (no mocking);
won't be able to properly use dependency injection frameworks;
code refactoring when using another concrete implementation.
The answer depends on the complexity of your ViewModel. If you are never going to create more than one implementation of an interface (including mocking), then there is no need to create the interface, so you can reduce the code and the overall maintenance burden.
That said the important things to consider are:
Can you unit test your view model, even without the interface (answer should be yes, otherwise you have some other problems IMO)
Can you still use a dependency injection framework (the answer is yes at least for some DI frameworks like Prism)
Are you only ever going to create one implementation of your ViewModel?
I believe that the mark of a well-designed ViewModel, should have a relatively simple implementation, and be easy to unit-test without having to resort to mocking.
So I have come across this best practices on Android articles on memory performance.
http://developer.android.com/training/articles/memory.html
They said
Avoid dependency injection frameworks
Using a dependency injection framework such as Guice or RoboGuice may
be attractive because they can simplify the code you write and provide
an adaptive environment that's useful for testing and other
configuration changes. However, these frameworks tend to perform a lot
of process initialization by scanning your code for annotations, which
can require significant amounts of your code to be mapped into RAM
even though you don't need it. These mapped pages are allocated into
clean memory so Android can drop them, but that won't happen until the
pages have been left in memory for a long period of time.
But what about Dagger which they claim to be fast. Not sure which one should I go for?
This recommendation does not apply equally to all dependency injection frameworks.
..frameworks [that work like Guice] tend to perform a lot of process initialization by scanning your code for annotations, which can require significant amounts of your code to be mapped into RAM even though you don't need it..
Thus, if using a DI/IoC framework that doesn't scan for said [run-time] annotations, implying the [excessive] use of reflection, then this reason doesn't apply. While Dagger does use annotations these are used differently than by Guice1 and avoid the problem stated.
Since Dagger was written as "A fast dependency injector for Android and Java", the authors have designed it for this purpose and believe that it is suitable for such a target - go ahead, give it a try.
1 Dagger uses compile-time annotations (well, mostly) instead of relying on run-time annotations and reflection; it is the run-time annotation scanning and reflection that causes the issue the memory guide was warning about.
The Android team has recently updated their recommendation to suggest developers use Dagger 2.
The previous recommendation was based on the high cost of reflection. Since Dagger 2 no longer uses reflection - Dagger 1 did - they believe it "can be used in Android apps without needless runtime cost or memory usage".
(Disclaimer: I'm the Dagger 2 team manager.)
The creator of Dagger, #JakeWharton, also wrote a simpler view "injection" framework called Butterknife
because all the RoboGuice converts were complaining about lack of
"view injection" with Dagger.
You use it like this:
class ExampleActivity extends Activity {
#InjectView(R.id.title) TextView title;
#InjectView(R.id.subtitle) TextView subtitle;
#InjectView(R.id.footer) TextView footer;
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
// TODO Use "injected" views...
}
}
Dependency injection best practices articles were recently added to Android developer official website. In these articles developers are encouraged to use Dagger 2 as a primary DI library for project medium (4-7 screens) and large (8+ screens) apps.
Dagger facilitates using DI in your app by creating and managing the graph of dependencies for you. It provides fully static and compile-time dependencies addressing many of the development and performance issues of reflection-based solutions such as Guice.
I'd like to know if there's anyone using Transfuse and how it differs from Android Annotations. I mean the pros and cons of each one, and if there are other options besides these two.
Thanks.
I may not count because I wrote the library, but I am an active user of Transfuse :-)
Here's the comparison from Transfuse's point of view:
Transfuse and Android Annotations share the same goal of reducing boilerplate and complexity in Android. Both Transfuse and Android Annotations are extremely performant as they use nearly identical techniques for generating code at compile time. In fact AA was one of many inspirations for Transfuse.
Android Annotations battles boilerplate by introducing code in the class extensions associated with the annotated classes. You can find the introduced code in the Class_ files in the generated source. Android Annotations includes a variety of features including a light dependency injection mechanism, a REST client generator, and a variety of Activity/Context enhancements among others.
Transfuse, on the other hand, approaches this goal through Dependency Injection, POJO components and Manifest Management among other ideas borrowed from Enterprise Java libraries. For instance, Transfuse Activities don't extend android.app.Activity. Instead you add functionality to your Activities via the annotations, which Transfuse uses to wire up the resulting generated code. Transfuse is also JSR330 compliant, which means it is a fully featured IOC/DI engine comparable with Guice (Roboguice) or Dagger. This gives the developer a lot of functionality to wire up object graphs behind the application without having to maintain the resulting code. Finally, one my my favorite features, Transfuse manages the writing of the AndroidManifest.xml file for you, so you don't have to remember to register your components. This is a huge time saver, especially when starting a new application.
I am asked this comparison question a fair amount, or how it compares with RoboGuice and Dagger. I should probably put together a comparison matrix to highlight the significant differences between the libraries.
I'm working on an Android project and I would like to know any recommendations about what's a good architecture to build an android application.
I want to use dependency injection using Roboguice and I've been reading about MVVM pattern or MVC pattern (Android MVVM Design Pattern Examples).
Also I know that roboguice have a pretty cool Context-Based Event's raising and handling feature that could be very testable as the code is decoupled.
Any recommendations on a working design pattern? a testable and scalable architecture you have worked with or developed?
The Android platform provides a common set of design patterns, and with the limited hardware resources you get compared to Web-apps it is still often best to stick with using these directly in production code. There are other frameworks that sort of "wrap" the base platform; these are worth looking into if you have a specific purpose (or perhaps for prototyping/experimenting), but for the best level of support you are generally best sticking with the standard components.
This is a great resource when working on UI solutions: http://www.androidpatterns.com/
Specifically for DI: There is a Spring framework for Android, I've had a play with it and it looks quite promising. You've already mentioned Roboguice as another alternative to this. However, to avoid performance and library overhead, I still find the easiest approach is to write a simple reflection-based class that registers and injects dependencies within my own code. Similar to this approach, except I usually move the injection code into a separate singleton and reference it from there.
In my experience most of the third-party offerings are not yet mature enough to rely on right now, and don't really give you much on top of what the base platform provides. They are constantly progressing, however, so be sure to experiment with the big names from time-to-time.
I'm debating using guice in an android project that is quite complex and has a lot of business logic. Guice seems like a good fit, but whenever I start reading deeper into it, it starts to look more complicated than it needs to be.
One thing I don't understand is: if Guice is so great and the best way to write java code, how come there is so little Android code that uses Guice... and why didn't Google use guice internally for Android?
Guice totally makes sense to be used and in fact is used in a whole bunch of applications. The extension RoboGuice adds some niceties for Android that makes it super productive to use.
In fact I can not imagine writing an Android app without it. Too painful.
Check out the links to apps using Roboguice on the website (e.g. Google Docs, OpenTable...). Also other apps like the Square app are known to use Guice directly.
It totally makes sense .. go do it!
Together with Robolectric it will also make your testing efforts easier.
PS: I am a committer on RoboGuice so I am partial ;-)
PPS - June 2013: Recent developments have given rise to other annotation/dependency injection based frameworks that do most of the work at build time and therefore avoid the performance hit of the runtime reflection (that is slow on Android) and are therefore more suitable for performance critical work - check out Dagger and AndroidAnnotations if you are interested in that.
Actually google discourages using Guice or RoboGuice in android applications due to memory overhead.
Source:
http://developer.android.com/training/articles/memory.html#DependencyInjection
5.11.2014 Edit:
There is a dedicated fast dependency injection library for android. I can see more and more people using it:
http://square.github.io/dagger/
13.04.2015 Edit:
Google released its own version of dagger, which does not use reflection in runtime:
http://google.github.io/dagger/
You know there is RoboGuice? It's Guice for Android.
The problem with demonstrating the strengths of a dependency injection framework is that it isn't possible to achieve it with a simple Hello World application. These frameworks show their value only in big systems with a lot of complexity. Also, they have a somehow steep learning curve.
Therefore it is quite normal that you can't find enough tutorials - open source projects that use Guice. This will be most often used in enterprise applications that do not get published.
As why Google doesn't use Guice, Guice doesn't fit everywhere. It adds a perfomance overhead and it doesn't make sense to use it in places, where it isn't needed.