2017-11-04 93 views
1

我有一个小场景,我有以下结构,我试图在baseActivity片段中注入片段管理器,但由于某种原因,我的运气不佳:(匕首2.11-与匹配键绑定存在于组件

@Singleton 
@Component(modules = { AppModule.class, 
     ActivityModule.class, 
     AndroidSupportInjectionModule.class }) 
public interface AppComponent extends AndroidInjector<App> { 

    @Override 
    void inject(App application); 

    @Component.Builder interface Builder { 

     @BindsInstance 
     AppComponent.Builder application(App application); 

     AppComponent build(); 
    } 
} 

ActivityModule.class

@PerActivity 
@ContributesAndroidInjector(modules = BaseActivityModule.class) 
abstract BaseActivity baseActivity(); 

BaseActivityModule.class

static final String ACTIVITY_FRAGMENT_MANAGER = "ACTIVITY_FRAGMENT_MANAGER"; 

@PerActivity 
@Named(ACTIVITY_FRAGMENT_MANAGER) 
@Provides 
static FragmentManager activityFragmentManager(BaseActivity activity) { 
    return activity.getSupportFragmentManager(); 
} 

个BaseAcitivity.class

public abstract class BaseActivity extends DaggerAppCompatActivity { 

    @Named(ACTIVITY_FRAGMENT_MANAGER) 
    @Inject 
    FragmentManager fragmentManager; 
} 

所以即使我提供的BaseActivityModule.class匕首我的片段经理抛出此以下错误。我甚至用Activity而不是BaseActivity作为BaseActivityModule中的输入参数。即使这样,我也会在这个问题上出现。不知道我究竟在搞什么。所以,任何帮助表示赞赏。在此先感谢:)

Error:(17, 8) error: [dagger.android.AndroidInjector.inject(T)] @javax.inject.Named("ACTIVITY_FRAGMENT_MANAGER") android.support.v4.app.FragmentManager cannot be provided without an @Provides- or @Produces-annotated method. 
@javax.inject.Named("ACTIVITY_FRAGMENT_MANAGER") android.support.v4.app.FragmentManager is injected at 
com.abc.views.base.BaseActivity.fragmentManager 
com.abc.views.def.ABCActivity is injected at 
dagger.android.AndroidInjector.inject(arg0) 
A binding with matching key exists in component: om.abc.views.base.BaseActivity_BaseActivity.BaseActivitySubcomponent 
+1

如何/你在注射?我猜你正在使用其他活动,而不是单个BaseActivity。您必须从其组件中提供依赖关系,BaseActivity会被忽略 –

回答

4

“相匹配的关键组件中存在一个结合”意味着你已经在你的整个对象图的地方必然的相关性,但它不能从那里需要被注入的子到达。这里是javadoc:看起来那么该建议用户,当在当前子未发现有约束力的其他地方存在匹配的所有子组件的结合图一键绑定

实用程序代码。如果在子或同级组件中存在与键匹配的绑定,那么用户实际上通常想要使用这种绑定。

例如,假设您有两个活动,ActivityAActivityB。您使用@ContributesAndroidInjector生成子组件,并在ActivityA模块中绑定Foo,但在ActivityB模块中未绑定Foo。如果您要求注射FooActivityB@Inject Foo foo,您将收到该错误消息。

在基类BaseActivity上使用@ContributesAndroidInjector形成子组件可能不是一个好方法。像在David Medenjak的评论中一样,基类的子组件将被忽略,具体类的子组件将在ABCActivity上执行注入。

现在,你可以通过在子结合FragmentManagerABCActivity改正错误:

@PerActivity 
@ContributesAndroidInjector(modules = BaseActivityModule.class) 
abstract ABCActivity ABCActivity(); 
+0

我明白你的观点。如果我不在'ABCActivityModule.class'中为'BaseActivity'创建一个子组件,并将其用作'@Module(includes = ABCActivityModule.class)'。它是否会工作? 当我尝试它会导致我相同的错误。 – user3354265

+0

@ user3354265你可以尝试做一个干净/重建?如果这不起作用,你可以发布你的'ABCActivityModule'吗? –

+0

刚刚做了没有改变。 BaseActivity模块与上面相同。 我仍然注入baseActivitity,但我只在我的ABCActivityModule中包含BaseActivityModule,它看起来像这样。 '@Module(包括= BaseActivityModule.class) \t公共抽象类ABCActivityModule { \t @PerFragment \t @ContributesAndroidInjector \t抽象ABCFragment abcFragment(); \t}' 此外,ABCActivity扩展了BaseActivity。所以我的主要要求是我想使用我的ABCActivity中的addFragment,这是我希望在BaseActivity中注入fragmentManager – user3354265

0

您是否尝试提供没有静态?

@Module(includes = {ViewModelModule.class}) 
public class AppModule { 

@Provides 
public PrefManager providePrefManager(Application app) { 
    return PrefManager.getInstance(app); 
} 
+0

静态方法的调用速度更快。删除静态对问题没有任何影响。 – user3354265