Dagger 2 injecting Android Context

放肆的年华 提交于 2019-11-26 16:48:51

问题


I am using Dagger 2 and have it working however I now need access to the Android Application Context.

Its not clear to me how to inject and get access to the context. I have tried to do this as follows:

@Module
public class MainActivityModule {    
    private final Context context;

    MainActivityModule(Context context) {
        this.context = context;
    }

@Provides @Singleton
Context provideContext() {
    return context;
}

However this results in the following exception:

java.lang.RuntimeException: Unable to create application : java.lang.IllegalStateException: mainActivityModule must be set

If I inspect the Dagger generated code this exception is raised here:

public Graph build() {  
    if (mainActivityModule == null) {
        throw new IllegalStateException("mainActivityModule must be set");
    }
    return new DaggerGraph(this);
}

I am not sure if this is the correct way to get Context injected - any help will be greatly appreciated.


回答1:


@Module
public class MainActivityModule {    
    private final Context context;

    public MainActivityModule (Context context) {
        this.context = context;
    }

    @Provides //scope is not necessary for parameters stored within the module
    public Context context() {
        return context;
    }
}

@Component(modules={MainActivityModule.class})
@Singleton
public interface MainActivityComponent {
    Context context();

    void inject(MainActivity mainActivity);
}

And then

MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
    .mainActivityModule(new MainActivityModule(MainActivity.this))
    .build();



回答2:


It took me a while to find a proper solution, so thought it might save some time for others, as far as I could gather this is the preferred solution with the current Dagger version (2.22.1).

In the following example I need the Application's Context to create a RoomDatabase (happens in StoreModule).

Please if you see any errors or mistakes let me know so I'll learn as well :)

Component:

// We only need to scope with @Singleton because in StoreModule we use @Singleton
// you should use the scope you actually need
// read more here https://google.github.io/dagger/api/latest/dagger/Component.html
@Singleton
@Component(modules = { AndroidInjectionModule.class, AppModule.class, StoreModule.class })
public interface AwareAppComponent extends AndroidInjector<App> {

    // This tells Dagger to create a factory which allows passing 
    // in the App (see usage in App implementation below)
    @Component.Factory
    interface Factory extends AndroidInjector.Factory<App> {
    }
}

AppModule:

@Module
public abstract class AppModule {
    // This tell Dagger to use App instance when required to inject Application
    // see more details here: https://google.github.io/dagger/api/2.22.1/dagger/Binds.html
    @Binds
    abstract Application application(App app);
}

StoreModule:

@Module
public class StoreModule {
    private static final String DB_NAME = "aware_db";

    // App will be injected here by Dagger
    // Dagger knows that App instance will fit here based on the @Binds in the AppModule    
    @Singleton
    @Provides
    public AppDatabase provideAppDatabase(Application awareApp) {
        return Room
                .databaseBuilder(awareApp.getApplicationContext(), AppDatabase.class, DB_NAME)
                .build();
    }
}

App:

public class App extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();

        // Using the generated factory we can pass the App to the create(...) method
        DaggerAwareAppComponent.factory().create(this).inject(this);
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }
}



回答3:


Was not correctly building the Application component, needed to pass in the Application. This Dagger 2 example perfectly shows how to do this: https://github.com/google/dagger/tree/master/examples/android-simple/src/main/java/com/example/dagger/simple

Update:
Working link: https://github.com/yongjhih/dagger2-sample/tree/master/examples/android-simple/src/main/java/com/example/dagger/simple



来源:https://stackoverflow.com/questions/30692501/dagger-2-injecting-android-context

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!