问题
I used to inject the current activity or activity context on some collaborators shared by several activities injecting the parent activity (BaseActivity or AppCompactActivity). But for some reason I cannot do it using Dagger 2.11 Android Injector.
This is my Activity Module:
@Module
public class ActivityModule {
private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
@Provides
@PerActivity
ActColaborator provideActCollaborator() {
return new ActColaborator();
}
@Provides
@PerActivity
Activity provideActivity() {
return activity;
}
}
I try to inject those classes:
@Inject
public Navigator(ActColaborator actColaborator,
BaseActivity activity) {
this.actColaborator = actColaborator;
this.activity = activity;
}
But I get a
BaseActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method.
If I remove the BaseActivity stuff, ActColaborator
is correctly injected.
The problem is that ActivityModule is not longer instantiated in the Activity passing it the Activity itself as it used to be:
//old, pre Android-injector code
this.activityComponent = getApplicationComponent()
.getActivityComponentBuilder()
.activityModule(new ActivityModule(this))
.build();
So I have no idea of how to make the current activity available for injection into its collaborators.
More info as requested: I have three different component classes for the three activities, but all of them like this:
@PerActivity
@Subcomponent
public interface MainActivityComponent extends AndroidInjector<MainActivity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MainActivity> {
}
}
And the ActivityBindingModule:
@Module(subcomponents = {
MainActivityComponent.class,
DetailActivityComponent.class,
AnotherActivityComponent.class
})
abstract public class ActivityBindingModule {
@Binds
@IntoMap
@ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory<? extends Activity> mainActivityInjectorFactory(
MainActivityComponent.Builder builder);
.....
回答1:
Ok, finally found what the problem was.
Using components with dependency or subcomponents I'm able to create the ActivityComponent
at the BaseActivity
level and then use it to inject properties into the top level activities.
Thas way, when I injected Activity
into collaborators the current ActivityComponent
that held the current Activity was used. Easy.
The problem with Android Injector is that we don't instantiate the ActivityComponent
from the code anymore, it is AndroidInjector
who does the magic, so we need to provide each Activity in its own module.
For example Main:
@Module
public abstract class MainActivityModule {
@Provides
@PerActivity
static Activity provideActivity(MainActivity activity) {
return activity;
}
}
Detail:
@Module
public abstract class DetailActivityModule {
@Provides
@PerActivity
static Activity provideActivity(DetailActivity activity) {
return activity;
}
}
Common provides:
@Module
public abstract class ActivityModule {
@Provides
@PerActivity
static ActColaborator provideActCollaborator() {
return new ActColaborator();
}
}
Then we declare them in Main:
@PerActivity
@Subcomponent(modules = { ActivityModule.class, MainActivityModule.class})
public interface MainActivityComponent extends AndroidInjector<MainActivity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MainActivity> {
}
}
And detail:
@PerActivity
@Subcomponent(modules = { ActivityModule.class, DetailActivityModule.class})
public interface DetailActivityComponent extends AndroidInjector<DetailActivity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<DetailActivity> {
}
}
And finally, we can inject the current activity in our shared collaborator:
private final Activity activity;
@Inject
public Navigator(Activity activity) {
this.activity = activity;
}
来源:https://stackoverflow.com/questions/44701292/how-to-inject-current-activity-in-a-collaborator-using-dagger-2-11-android-injec