J'utilise Dagger 2 et je le fais fonctionner, mais j'ai maintenant besoin d'accéder au contexte d'application Android.
Ce n'est pas clair pour moi comment injecter et accéder au contexte. J'ai essayé de le faire comme suit:
@Module
public class MainActivityModule {
private final Context context;
MainActivityModule(Context context) {
this.context = context;
}
@Provides @Singleton
Context provideContext() {
return context;
}
Cependant, cela entraîne l'exception suivante:
Java.lang.RuntimeException: impossible de créer l'application: Java.lang.IllegalStateException: mainActivityModule doit être défini
Si j'inspecte le code généré par Dagger, cette exception est déclenchée ici:
public Graph build() {
if (mainActivityModule == null) {
throw new IllegalStateException("mainActivityModule must be set");
}
return new DaggerGraph(this);
}
Je ne sais pas si c'est la bonne façon d'injecter du contexte - toute aide sera grandement appréciée.
Ne générait pas correctement le composant Application, nécessaire pour transmettre l'application. Cet exemple de Dagger 2 montre parfaitement comment procéder: https://github.com/google/dagger/tree/master/examples/Android-simple/src/main/Java/com/example/dagger/simple
Mise à jour:
Lien de travail: https://github.com/yongjhih/dagger2-sample/tree/master/examples/Android-simple/src/main/Java/com/example/dagger/simple
@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);
}
Et alors
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(MainActivity.this))
.build();
Il m'a fallu un certain temps pour trouver une solution appropriée, alors j'ai pensé que cela pourrait faire gagner du temps aux autres, pour autant que je sache, c'est la solution préférée avec la version actuelle de Dagger (2.22.1).
Dans l'exemple suivant, j'ai besoin du Application
Context
pour créer un RoomDatabase
(se produit dans StoreModule
).
S'il vous plaît, si vous voyez des erreurs ou des erreurs, faites-le moi savoir afin que j'apprenne aussi :)
Composant:
// 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;
}
}