Dagger and Butter Knife vs. Android Annotations
Asked Answered
H

8

63

I am evaluating Dependency Injection (DI) frameworks for an Android app. The top contenders are: Dagger (with Butter Knife) and Android Annotations. I understand that Dagger and ButterKnife are from the same source- square and they complement each other. Here're are the key matrices that I am looking for:

  1. Ease of use (our build is based on Gradle and we use Android Studio IDE)
  2. Testing support (we use Robotium for functional testing and RoboLectric for unit testing)
  3. Performance (DI frameworks use reflection, which one is faster?)
Hyetal answered 22/6, 2014 at 13:39 Comment(6)
google specifically asks not to use dependency injection developer.android.com/training/articles/memory.html#AndroidCloset
@IllegalArgument that link just says "those frameworks tend to do a lot of initialization process to scan annotations". Dagger and AndroidAnnotations (probably also Butter Knife as it claims but I'm not sure) all do their magic at compile time that may not be applicable.Donnydonnybrook
See reddit.com/r/androiddev/comments/28vlrt/…Lelea
Note: both Dagger and Android Annotations don't use reflection.Cuckooflower
Unbiased by-the-numbers comparison: codix.io/cmp/Android%20Dependency%20Injection%20LibrariesFibre
I don't know if the docs changed, but now it says to use Dagger for dependency injection developer.android.com/topic/performance/…Guiltless
L
53

AndroidAnnotations
uses compile time annotation processing. It generates a sub class with an underscore apppended to the original name (MyActivity_ generated from MyActivity). So to have it work you always have to use the generated class for references instead of your original class.

It has a very rich feature set, see the list of available annotations.

Butterknife
uses also compile time annotation processing, but it generates finder classes which are used by a central class (ButterKnife). This means that you can use your original class for referencing, but you have to call the injection manually. A copy from the ButterKnife introduction:

@Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.inject(this);
    // TODO Use "injected" views...
}

The feature set is not so rich, ButterKnife supports view injection (AndroidAnnotations equivalent would be @ViewByIdand @ViewsById) and some event binding (for a complete list see the namespace directory here, just count the OnXXX event annotations).

Dagger
is a DI implementation for Android, similar to Guice. It also uses compile time annotation processing and generates object graphs which you use for manually injection. You distinguish between application object graph and scoped object graphs for injecting e.g. in activities. Here you see an Application.onCreate example:

@Override public void onCreate() {
    super.onCreate();
    objectGraph = ObjectGraph.create(getModules().toArray());
    objectGraph.inject(this);
    // use injected classes
}

I found it is harder to start with dagger, but this might be only my experience. However see some videos here for a better start: 1, 2

From the feature set point of view I would say that Dagger implements functionalities which could be compared to AndroidAnnotation's @EBean and @Bean functionality.

Summary
If you are comparing ease of use, testing support and performance I can't find much difference between using AndroidAnnotation and ButterKnife+Dagger. Differences are in the programming model (use classes with _ instead of using the original ones and call the injection manually) and in the feature set.

AndroidAnnotation gives you a full list of functionalities, but ties you to certain libraries. For example if you use it's rest api you have to use Spring Android. You also have annotations for features like OrmLite (@OrmLiteDao) regardless if you use OrmLite or not.

At the end it is a matter of taste, at least in my opinion.

Lelea answered 30/9, 2014 at 17:16 Comment(6)
I think you made a mistake about ButterKnife: it uses compile time Annotation (RetentionPolicy.CLASS), but it inject code at runtime, resulting greater effort of time.Ardolino
I think that all solutions produce code during the compile time and this code is called (at runtime) to perform the injection. In Android Annotations for example it generates a subclass (MyActivity_) which performs the injection for MyActivity. In Butterknife you have to call ButterKnife.inject(this) which delegates to the generated code.Lelea
No love for Android's own Data binding library? developer.android.com/tools/data-binding/guide.html You'll eventually forget all that.Emogeneemollient
Sorry for digging out. the last paragraph is no more correct. Android Annotations is now modular, so you can include OrmLite-Support just if you really use OrmLite.Schofield
I'd like to know your oppinion on the access modifiers. For example you cannot use private access modifiers with some of these libraries, at least Android Annotations from my experience. How does this affect the security of the app. Would this imply a risk?Dight
Since Android Annotations is based on inheritance, you have to use protected access modifiers. Yes, this is weaker than private, but does not affect security or impy any risk.Lelea
T
19

Here is the Nice article in Dzone blog.

We to need to compare the features of each, such as :

  • Minimum Jars required
  • ActionBarSherlock compatibility
  • Injection for click listeners
  • POJO injection
  • Performance

enter image description here

Only Pojo Injection missing in butterknife! So looks like Butterknife is the winner!

Source

Tisdale answered 1/10, 2014 at 11:44 Comment(2)
Another row I would consider adding to this chart is "Support for Library Projects" which Butterknife does not support, but AndroidAnnotations does via the resName attribute (see github.com/excilys/androidannotations/wiki/Library-projects). This was a dealbreaker for me using Butterknife.Presume
-1: the question was not about RoboGuice (which is anyway retired and not maintained any longer), but about AndroidAnnotationsBalneal
C
7

Google does ask specifically not to use dependency injection.

But by reading their request they seem to be referring more to the Guice and reflection based DI library's. Libraries such as android annotation use no reflection instead employing compile time generated code, while butterknife and dagger uses a small amount of reflection optimised for android but are supposedly slightly more powerful than android annotation. It really depends on the project and how much of a performance hit you are willing to take. In my opinion just using butterknife is sufficient to speed up code development by itself. If you need slightly more use android annotation and lastly if you are willing to take a slight performance hit due to reflection the best option without absolutely destroying performance with a powerhouse Guice based reflection use dagger + butterknife.

Crossfertilize answered 26/9, 2014 at 22:57 Comment(1)
They made their own, that's why: developer.android.com/tools/data-binding/guide.html youtube.com/watch?v=5sCQjeGoE7MEmogeneemollient
D
5

You should give a try at Toothpick.

Toothpick is (per the README):

  • pure java
  • fast, it doesn't use reflection but annotation processing
  • simple, flexible, extensible & powerful, robust & tested
  • thread safe
  • documented & Open Source
  • scope safe : it enforces leak free apps
  • test oriented : it makes tests easier
  • it works very well with Android or any other context based framework (such as web containers)

It can even be faster than Dagger 2 in most cases, and it's much simpler.

Note: Yes, I am one of the authors.

Distasteful answered 9/12, 2016 at 6:17 Comment(1)
Can we use Android annotation processor for Toothpick?Tirzah
F
3

Use Android Annotations or Butterknife to ease your coding. But don't go for Roboguice! Roboguice forces your activies, fragments to extend to roboguice classes. Not fun, at all!

Dagger 2 is a much better option. You can use it along with Android Annotations if you'd like. I would just use Android Annotations for a simple app, but these days is good to work more with Dagger.

Frigidaire answered 4/7, 2015 at 18:45 Comment(2)
Whats the problem in extending from RoboActivity (that extends from Activity) while you can extend from Activity? you are not losing anything here.Kendyl
It's an old library. It used to force you to use their Android component flavors. Now the best option is Dagger 2. Good luck.Frigidaire
R
1

Seems like Google chooses dagger, as they are developing it jointly with Square, who created it.

Concerning Butterknife and Dagger themselves, there is the SO question difference-between-dagger-and-butterknife-android which clarifies how they complement each other.

Retrench answered 3/7, 2015 at 10:53 Comment(0)
R
1

The reddit-thread mentioned by @ChrLipp has someone who used all three on the same project, speaks highly of dagger+butterknife but also gives AndroidAnnotations its place:

For dependency injection, butterknife is used for Views, Dagger is used for all objects and is highly recommended and Android Annotations creates more of a framework for developing Android instead of injecting objects into your classes so each library are quite different from each other. Dagger is equivalent to Guice but is much much faster. Dagger is more powerful then ButterKnife and Android Annotations as it injects all objects rather than ButterKnife and Android Annotations which only inject a certain set of objects.

Dagger can be a pain to setup and configure but is well worth it once you have it done. But then again, because these are all quite different from each other, it all depends on what your needs are for the project.

Also, speaking of each one being quite different, in your project you can use ButterKnife, Android Annotations and Dagger all in the same project if you really want to. They each have the same idea but do something different so you could use them all.

Retrench answered 3/7, 2015 at 10:56 Comment(0)
E
1

Eventually if you use one of the three, you'll have a hard time transitioning to Android's databinding. That's what's fastest if you need to consider performance:

https://developer.android.com/tools/data-binding/guide.html

Emogeneemollient answered 28/4, 2016 at 15:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.