如何使用Dagger 2.11 Android注入器在协作者中注入当前活动 [英] How to inject current activity in a collaborator using Dagger 2.11 Android injector
问题描述
我曾经将当前活动或活动上下文注入由注入父活动(BaseActivity或AppCompactActivity)的多个活动共享的一些协作者。
但由于某些原因,我无法使用Dagger 2.11 Android Injector做到这一点。
这是我的活动模块:
@Module
公共类ActivityModule {
私人最终Activity活动;
public ActivityModule(Activity activity){
this.activity = activity;
}
@Provides
@ PerActivity
ActColaborator ProvideActCollaborator(){
返回新的ActColaborator();
}
@Provides
@PerActivity
Activity ProvideActivity(){
return activity;
}
}
我尝试注入这些类:
@Inject
public Navigator(ActColaborator actColaborator,
BaseActivity活动){
this.actColaborator = actColaborator;
this.activity =活动;
}
但是我得到了
没有$ Inject构造函数或@Provides注释方法,就无法提供
BaseActivity。
如果我删除了BaseActivity内容,则 ActColaborator
正确注入。
问题在于,ActivityModule不再在Activity中实例化,而将过去的活动本身传递给了它:
//旧的Android注入器代码
this.activityComponent = getApplicationComponent()
.getActivityComponentBuilder()
.activityModule(new ActivityModule(this)
.build() ;
所以我不知道如何使当前活动可用于注入其合作者。 p>
根据要求提供更多信息:
我为这三个活动提供了三个不同的组件类,但它们都像这样:
@PerActivity
@Subcomponent
公共接口MainActivityComponent扩展了AndroidInjector< MainActivity> {
@ Subcomponent.Builder
抽象类Builder扩展了AndroidInjector.Builder< MainActivity> {
}
}
和ActivityBindingModule:
@Module(子组件= {
MainActivityComponent.class,
DetailActivityComponent.class,
AnotherActivityComponent.class
})
抽象公共类ActivityBindingModule {
@Binds
@IntoMap
@ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory< ;?扩展Activity> mainActivityInjectorFactory(
MainActivityComponent.Builder builder);
.....
好,终于找到了问题所在。
使用具有依赖项或子组件的组件,我可以在 BaseActivity
级别创建 ActivityComponent
使用它将属性注入顶级活动。
这样,当我将 Activity
注入协作者时,当前的 ActivityComponent $ c使用了保存当前活动的$ c>。
Android Injector的问题是我们不再从代码中实例化 ActivityComponent
了,它是 AndroidInjector
发挥作用的人,因此我们需要在自己的模块中提供每个Activity。
例如Main :
@Module
公共抽象类MainActivityModule {
@Provides
@PerActivity
静态活动offerActivity(MainActivity活动){
返回活动;
}
}
详细信息:
@Module
公共抽象类DetailActivityModule {
@Provides
@PerActivity
静态活动provideActivity(DetailActivity活动){
退货活动;
}
}
常见规定:
@Module
公共抽象类ActivityModule {
@Provides
@PerActivity
静态ActColaborator offerActCollaborator(){
返回新的ActColaborator();
}
}
然后我们在Main中声明它们:
@PerActivity
@Subcomponent(modules = {ActivityModule.class,MainActivityModule.class})
公共接口MainActivityComponent扩展了AndroidInjector< ; MainActivity> {
@ Subcomponent.Builder
抽象类Builder扩展了AndroidInjector.Builder< MainActivity> {
}
}
详细信息:
@PerActivity
@Subcomponent(modules = {ActivityModule.class,DetailActivityModule.class})
公共接口DetailActivityComponent扩展了AndroidInjector< DetailActivity> {
@ Subcomponent.Builder
抽象类Builder扩展了AndroidInjector.Builder< DetailActivity> {
}
}
最后,我们可以将当前活动注入我们共享的协作者:
私人最终活动活动;
@Inject
public Navigator(活动活动){
this.activity = activity;
}
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);
.....
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;
}
这篇关于如何使用Dagger 2.11 Android注入器在协作者中注入当前活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!