Dagger: The correct way to define an injection class that takes a context in its constructor

I want to use dagger (dagger v1 by Square) to create a singleton class whose constructor requires context as an argument. Then I want to inject this singleton class into my MainActivity. What are the correct steps to determine this?

I tried to do this:

SingletonClass:

@Module(
    injects = {MainActivity.class}
)
@Singleton
public class SingletonClass {
...

@Inject
SingletonClass(Context ctx) {}
}

      

to which I get the error:

no injectable members on android.content.Context

      

I understand that the SingletonClass has to get its context from somewhere to be injected, but since I no longer "call" it in the traditional sense, but instead I inject it like this in MainActivity at the class level:

@Inject SingletonClass singletonClass;

      

how should I pass this context?

Here are the additional files I created for the dagger (two of which I saw in the official examples):

AndroidModule:

@Module(library = true, injects = MainActivity.class)
public class AndroidModule {

private final Context context;

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

/**
 * Allow the application context to be injected but require that it be
 * annotated with to explicitly
 * differentiate it from an activity context.
 */
@Provides
@Singleton
@ForApplication
Context provideApplicationContext() {
    return context;
}


}

      

App.class (for extending my app):

public class App extends Application {
private static final String TAG = App.class.getSimpleName();
private static App instance;
public MainActivity mainActivity;
private static Context context;
private ObjectGraph objectGraph;

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

    instance = this;
    context = getApplicationContext();

    objectGraph = ObjectGraph.create(getModules().toArray());
}

public static App getInstance() {
    return instance;
}

public static Context getContext() { return context; }

protected List<Object> getModules() {
    return Arrays.asList(new AndroidModule(this), new App());
}

public void inject(Object object) {
    objectGraph.inject(object);
}
}

      

ApplicationApplication class:

import java.lang.annotation.Retention;
    import javax.inject.Qualifier;

    import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Qualifier @Retention(RUNTIME)
public @interface ForApplication {
}

      

+3


source to share


1 answer


You need to add a qualifier @ForApplication

to your parameter Context

in the constructor SingletonClass

.

The dagger is now looking Context

for injection, but only has @ForApplication Context

that is a mismatch.

@Singleton
public class SingletonClass {

    @Inject
    SingletonClass(@ForApplication Context ctx) {
    }

}

      



Now you can also get rid of the line library = true

in AndroidModule

which you probably added because Dagger warned you that it was @ForApplication Context

not used (don't ignore those warnings!).

Also, and it might just be a copy-paste error, this SingletonClass

one shouldn't contain annotation @Module

.

+3


source







All Articles