Dagger 2.11 - 组件中存在具有匹配键的绑定

时间:2017-11-04 02:35:25

标签: android dependency-injection dagger-2 dagger

我有一个小方案,我有以下结构,我试图在baseActivity Fragment中注入片段管理器,但由于某种原因我运气不好:(

@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中提供我的片段管理器,dagger也会抛出以下错误。我甚至尝试使用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

2 个答案:

答案 0 :(得分:8)

&#34;组件中存在具有匹配键的绑定&#34;意味着您已在整个对象图中的某处绑定了一个依赖项,但无法从需要注入它的子组件中访问它。这是javadoc

  

实用程序代码,用于查找与绑定图中所有子组件中的键匹配的绑定,以便在当前子图中找不到绑定时,建议用户在其他位置存在绑定。如果匹配键的绑定存在于子组件或兄弟组件中,那通常是什么   用户实际上想要使用。

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

BaseActivity等基类上使用ABCActivity形成子组件可能不是一个好方法。与David Medenjak的注释一样,基类的子组件将被忽略,具体类的子组件将在FragmentManager上执行注入。

目前,您可以通过在ABCActivity的子组件中绑定@PerActivity @ContributesAndroidInjector(modules = BaseActivityModule.class) abstract ABCActivity ABCActivity(); 来修复错误:

INSERT INTO `views` (post_id, view_count, view_ip)
VALUES (?, 1, ?)
ON DUPLICATE KEY UPDATE view_count = view_count + 1;

答案 1 :(得分:0)

您是否尝试过无静电提供?

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

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