ошибка: [Dagger / IncompatiblyScopedBindings] (unscoped) может не ссылаться на привязки области: - PullRequest
0 голосов
/ 21 декабря 2018

Я не понимаю, как решить эту ошибку.Я получил эту ошибку после попытки добавить фрагменты в мое приложение и использовать Dagger для DI.Вот стек ошибок:

ошибка: [Dagger / IncompatiblyScopedBindings] di.component.ApplicationComponent (unscoped) может не ссылаться на привязки областей: @Provides @ di.ApplicationContext @ di.ApplicationScope android.content.СодержаниеKeyStoreServiceInterface di..Module.CoinmarketcapModule.getCoinmarketcapService (com.google.gson.Gson, okhttp3.OkHttpClient) @Provides @ di.ApplicationScope com.google.gson.Gson di.Module.GsonModule.getGson () @Provides @ di.ApplicationScope okhttp3.OkHttpClient di.Module.OkHttpModule.getOkHttpClient () @Provides @ di.ApplicationScope repository.WalletRepositoryInterface*

Вот мой класс ApplicationComponent:

@Component(modules = {ApplicationContextModule.class,
        SharedPreferencesModule.class,
        KeyStoreModule.class,
        SharedPreferenceHelperModule.class,
        AndroidInjectionModule.class,
        BindModule.class,
        AndroidSupportInjectionModule.class,
        OkHttpModule.class,
        GsonModule.class,
        CoinmarketcapModule.class,
        WalletRepositoryModule.class})
@SuppressWarnings("unchecked")
public interface ApplicationComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(MyApplication myApplication);
        ApplicationComponent build();
    }

    void inject(MyApplication myApplication);

    @ApplicationContext
    Context getApplicationContext();

    SharedPreferences getSharedPreferences();

    KeyStoreServiceInterface getKeyStoreService();

    SharedPreferencesHelper getSharedPreferencesHelper();

    CoinmarketcapService getCoinmarketcapService();

    WalletRepositoryInterface getWalletRepository();

}

У меня есть аннотация FragmentScope и ActivityScope в моем коде Android.Это просто обычные возможности для Dagger с Retention.RUNTIME.Вот мой код приложения:

public class MyApplication extends MultiDexApplication implements HasActivityInjector, HasFragmentInjector {

    private ApplicationComponent applicationComponent;

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
    @Inject
    DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;

    @Override
    public void onCreate() {

        super.onCreate();

        DaggerApplicationComponent
                .builder()
                .application(this)
                .build()
                .inject(this);

        Timber.plant(new Timber.DebugTree());
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingActivityInjector;
    }

    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }

    @Override
    public AndroidInjector<Fragment> fragmentInjector() {
        return fragmentDispatchingAndroidInjector;
    }
}

Любая помощь будет оценена.

РЕДАКТИРОВАТЬ: мне удалось решить эту проблему, добавив @ApplicationScope к моему компоненту.Почему я должен это сделать?До добавления фрагментов и @FragmentScope в мой код (до этого у меня были только @activityscope и @applicationscope) У меня не было этой проблемы, она появилась только после добавления фрагментов?Если кто-то может помочь ответить на этот вопрос, все равно стоит принять этот ответ, чтобы помочь кому-то еще, кто может иметь эту проблему и хочет понять ее.

1 Ответ

0 голосов
/ 21 декабря 2018

Вы не показали нам ApplicationContextModule, но из вашего сообщения об ошибке он, вероятно, содержит следующее:

@Provides @ApplicationContext @ApplicationScope
Context getApplicationContext(MyApplication application) {
  return application.getApplicationContext();
}

Вы аннотировали этот @Provides метод с помощью @ApplicationScope, который инструктирует Dagger сохранитьвозвратил Контекст внутри Компонента - в частности, компонента, который вы также аннотировали @ApplicationScope.До того, как вы внесли изменения в ваше редактирование, не было совпадений @ApplicationScope, и Даггер дал вам это сообщение.Теперь, когда он у вас есть, Даггер знает, где хранить сохраненный экземпляр контекста.

Смущает В общем, Даггер не будет возражать против неуместных привязок, которые вы еще не используете, поэтому Даггер победилне возражайте против отсутствия аннотации в области действия компонента, пока вы не начнете использовать привязки в этой области, что, вероятно, произошло примерно в то же время, когда вы ввели область действия фрагмента.

См. также Руководство пользователя кинжала :

Поскольку Dagger 2 связывает экземпляры области в графе с экземплярами реализаций компонентов, самим компонентам необходимо объявить, какую область они намерены представлять.Например, не имеет смысла иметь привязку @Singleton и привязку @RequestScoped в одном и том же компоненте, поскольку эти области имеют разные жизненные циклы и, следовательно, должны жить в компонентах с разными жизненными циклами.Чтобы объявить, что компонент связан с заданной областью действия, просто примените аннотацию области действия к интерфейсу компонента.

Примечательно, что экземпляр Application также не изменяется в течение времени жизни компонента иОжидается, что значение getApplicationContext не изменится за время существования приложения.Это означает, что ваша сфера на самом деле не дает вам много, кроме как избегать повторных вызовов вашего getApplicationContext метода в ApplicationContextModule.


«Но подождите, я вас слышу»считать.«Почему Dagger не знает , что моя привязка @ApplicationScoped принадлежит моему ApplicationComponent? В конце концов, Dagger видит ApplicationContextModule установленным на ApplicationComponent, поэтому единственный способ, который имеет смысл, - это если ApplicationComponent неявно @ApplicationScoped."Две причины: во-первых, в некотором смысле это принудительная документация, которая также помогает Dagger более четко определить, какая привязка ошибочна, чтобы вы случайно не установили привязки @ActivityScoped непосредственно в свой ApplicationComponent и не убедили Dagger, что ваш компонент одновременно является приложением.ограниченный и ограниченный по активности.Во-вторых, вы также можете аннотировать инъецируемый класс аннотацией области видимости, и Dagger не сможет ничего вывести, потому что нет отношения компонент-установка-модуль, который он мог бы прочитать.Между этими двумя, Dagger заставляет вас аннотировать ваш Компонент в документах, которые я цитировал выше.

...