Dagger Android Tutorial 1

How to do dagger-android

Guowei Lv

2 minute read

Warning: Google thinks you should avoid dagger-android for new projects. Watch Here

But, if you are using it now, here are some notes on how to approach it.

This is basically a text version of these videos

Application Component

Pretty much every app will have an application component, whose scope will be the lifetime of the application.

First, create the AppComponent

//1. Include this 'AndroidSupportInjectionModule', this is required
@Component(modules = {AndroidSupportInjectionModule.class})
public interface AppComponent extends AndroidInjector<BaseApplication> {//2. Extends 'AndroidInjector<BaseApplication>'

    //3. Add a factory. This basically says that an AppComponent needs an Application, and it will expose it
    @Component.Factory
    interface Factory {
        AppComponent create(@BindsInstance Application application);
    }
}

Then create a custom application class like this.

// 1. Extends DaggerApplication
public class BaseApplication extends DaggerApplication {

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        // 2. Create the app component with this as application
        return DaggerAppComponent.factory().create(this);
    }
}

Injecting into Activities

Now let’s see how to inject into activities.

First the activity must extends DaggerAppCompatActivity.

public class AuthActivity extends DaggerAppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Then, create module ActivityBuildersModule.

@Module
abstract class ActivityBuildersModule {
    
    // This means we want to inject into AuthActivity
    @ContributesAndroidInjector
    abstract AuthActivity contribute();
}

And add this module into AppComponent.

@Component(modules = {AndroidSupportInjectionModule.class, ActivityBuildersModule.class})
public interface AppComponent extends AndroidInjector<BaseApplication> {
 ...
}

AppModule

AppModule will be responsible to provide some application level objects.

Create the following module class.

@Module
class AppModule {

    // Always prefer static method for performance matters
    @Provides
    static RequestOptions provideRequestOptions() {
        return RequestOptions
                .placeholderOf(R.drawable.white_background)
                .error(R.drawable.white_background);
    }

    @Provides
    static RequestManager provideGlideInstance(Application application, RequestOptions requestOptions) {
        return Glide.with(application).setDefaultRequestOptions(requestOptions);
    }

    @Provides
    static Drawable provideAppDrawable(Application application) {
        return ContextCompat.getDrawable(application, R.drawable.logo);
    }
}

Remember to also include this in the AppComponent.

Singleton Scope

Let’s give the AppComponent the Singleton scope.

@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, ActivityBuildersModule.class, AppModule.class})
public interface AppComponent extends AndroidInjector<BaseApplication> {
 ...
}

This means the AppComponent owns the @Singleton scope. Whatever dependencies that are also marked as @Singleton, their lifetime/scope will be tied to the AppComponent. It does not have to be @Singleton, it can be whatever annotation.

we can now give all the provides methods in the AppModule the @Singleton annotation.

@Module
class AppModule {

    @Singleton
    @Provides
    static RequestOptions provideRequestOptions() {
        return RequestOptions
                .placeholderOf(R.drawable.white_background)
                .error(R.drawable.white_background);
    }

    @Singleton
    @Provides
    static RequestManager provideGlideInstance(Application application, RequestOptions requestOptions) {
        return Glide.with(application).setDefaultRequestOptions(requestOptions);
    }

    @Singleton
    @Provides
    static Drawable provideAppDrawable(Application application) {
        return ContextCompat.getDrawable(application, R.drawable.logo);
    }
}

That’s it for now. Stay tuned!

comments powered by Disqus