Dagger 2.11 - в компоненте существует привязка с соответствующим ключом

У меня есть небольшой сценарий, в котором у меня есть следующая структура, где я пытаюсь внедрить менеджер фрагментов в фрагмент BaseActivity, но по какой-то причине мне не хватает удачи:(

@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

2 ответа

Решение

"Привязка с совпадающим ключом существует в компоненте" означает, что вы связали зависимость где-то на всем объектном графе, но она не может быть достигнута из подкомпонента, в который ее нужно внедрить. Вот этот Javadoc:

Код утилиты, который ищет привязки, соответствующие ключу во всех подкомпонентах графа привязки, так что пользователю рекомендуется, чтобы привязка существовала в другом месте, когда она не найдена в текущем подграфе. Если в подчиненном или дочернем компоненте существует привязка, соответствующая ключу, это часто то, что пользователь фактически хочет использовать.

Например, предположим, у вас есть два вида деятельности, ActivityA а также ActivityB, Вы создаете субкомпоненты с @ContributesAndroidInjector и связать Foo в ActivityA модуль, но не ActivityB модуль. Если вы запрашиваете инъекцию для Foo в ActivityB с @Inject Foo foo вы получите это сообщение об ошибке.

Формирование субкомпонентов с использованием @ContributesAndroidInjector на базовом классе, как BaseActivity вероятно, не очень хороший подход. Как и в комментарии David Medenjak, подкомпонент для базового класса будет проигнорирован, а подкомпонент для конкретного класса выполнит внедрение ABCActivity,

Сейчас вы можете исправить ошибку, связав FragmentManager в подкомпоненте для ABCActivity:

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

Вы пытались обеспечить без статического?

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

@Provides
public PrefManager providePrefManager(Application app) {
    return PrefManager.getInstance(app);
}
Другие вопросы по тегам