Dagger and Butter Knife vs. Android Annotations

user3277846 picture user3277846 · Jun 22, 2014 · Viewed 31.2k times · Source

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?)

Answer

ChrLipp picture ChrLipp · Sep 30, 2014

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.