Last year I wrote MeasureMe a native Android application. I have just started a new project I find it interesting the difference in tools and techniques I am using only 18 months after MeasureMe.

At the time I identified four main areas that I addressed first.

  1. Logging
  2. Inversion of Control / Dependency Injection
  3. Unit Testing
  4. Automated Building

In 2014 I used eclipse and ant to control the build process, logging was handled by slf4j and logback, for dependency injection i used roboguice and UnitTesting was done on pure java classes using JUnit.

In 2015 I have made some changes. I now use AndroidStudio and Gradle to build the application. I still use JUnit to write unit tests however Google has made life much easier and there is now a mock android layer available. I also use RoboElectric to extend the reach of the tests. Logging has remains the same and I am very happy with slf4j and logback.

I have moved to Dagger2 for dependency injection. Last year I used RoboGuice and at the time it was a close call between it and Dagger1. In the end I chose RoboGuice largely because the syntax was more familiar and there appeared to be more support and examples for it.

One of the issues I had with Dagger was that injecting each class was a bit clunky, but as it turned out given that I needed to work with ActionBar activity and at the time RoboGuice did not support using the compatibility libraries so I needed to write the clunky code to inject the activities anyway.

I noticed that Google had forked the original Square implementation of dagger and appeared to be doing a lot of work on it. I liked the purely generated approach both for speed and debugging so I decided to switch. For comparison with the other two dependency injection mechanisms the fragment or activity class looks like this

public class RecommendationListFragment extends BaseFragment {
 @Inject
 ILoggerFactory logger;

 protected ApplicationComponent getApplicationComponent(Activity activity) {
  return ((AndroidApplication) activity.getApplication())
    .getApplicationComponent();
 }

 protected boolean isInjected() {
  return logger != null;
 }

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  getApplicationComponent(getActivity()).inject(this);
 }

 @Override
 public void onResume() {
  super.onResume();
  if (!isInjected()) {
   getApplicationComponent(getActivity()).inject(this);
  }
 }

I dont remember having to write the onResume code for RoboGuice but it seems like a small detail. The IoC container looked like this

@Module
public class ApplicationModule {
 private final AndroidApplication application;

 public ApplicationModule(AndroidApplication application) {
  this.application = application;
 }

 @Provides
 @Singleton
 Context provideApplicationContext() {
  return this.application;
 }

 @Provides
 @Singleton
 ILoggerFactory provideLogger(SlfLoggerFactory loggerFactory) {
  return loggerFactory;
 }
}

The application sets up the container like this

public class AndroidApplication extends Application {
 private ApplicationComponent applicationComponent;

 final private Logger logger = LoggerFactory.getLogger(AndroidApplication.class);

 @Override
 public void onCreate() {
  logger.warn("Application started");
  super.onCreate();
  this.applicationComponent = initialiseInjector();
  logger.debug("Application IoC bound");
 }

 protected ApplicationComponent initialiseInjector() {
  return DaggerApplicationComponent.builder()
    .applicationModule(new ApplicationModule(this))
    .build();
 }

 public ApplicationComponent getApplicationComponent() {
  return this.applicationComponent;
 }

Where the DaggerApplicationComponent is generated code.

So far I have been pleased with Dagger2 in the sense that it just works and I’ve not had any weird behaviour. I have also started to extend what I do with dependency injection, I have started using scoped containers with presenters and unit tests using a mocked container. I will cover this in another post.