错误:[Dagger/IncompatiblyScopedBindings](未范围化)可能未引用范围化绑定:



我不知道如何解决这个错误。在尝试将碎片添加到我的应用程序并使用Dagger进行DI之后,我出现了这个错误。以下是错误堆栈:

错误:[Dagger/IncompatiblyScopedBindings]di.component.ApplicationComponent(unscoped)不能引用scoped绑定:@提供@di。ApplicationContext@di。ApplicationScopeandroid.content.Contextdi。单元ApplicationContextModule.getApplicationContext(application.MyApplication)@提供@di。ApplicationScope android.content.Shared首选项di。单元SharedPreferencesModule.getSharedPreferences(@di.ApplicationContextandroid.content.Context)@提供@di。ApplicationScope服务KeyStoreServiceInterfacedi。单元KeyStoreModule.getKeyStoreService(@Named("KEY_STORE_FILE")java.io.File)@提供@di。ApplicationScope存储库。共享首选项帮助程序di。单元SharedPreferencesHelperModule.getSharedPreferencesHelper()@提供@di。ApplicationScope服务。Coinmarketcap服务di。单元CoinmarketcapModule.getCoinmarketcapService(com.google.gson.gson,okhttp3.OkHttpClient)@提供@di。ApplicationScopecom.google.gson.gson di。单元GsonModule.getGson()@提供@di。ApplicationScope okhttp3.OkHttpClientdi。单元OkHttpModule.getOkHttpClient()@提供@di。ApplicationScope存储库。WalletPositionInterfacedi。单元WalletpositoryModule.getWalletpository(存储库.SharedPreferencesHelper,服务KeyStoreService)

这是我的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();
}

我的android代码中有一个FragmentScope和一个ActivityScope注释。这只是保留dagger的常规瞄准镜。运行时。这是我的申请代码:

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),我没有这个问题,它只是在添加碎片后出现的?如果有人能帮助回答这个问题,那么接受这个答案来帮助其他可能有这个问题并想了解它的人仍然是值得的

您还没有向我们显示ApplicationContextModule,但从您的错误消息来看,它可能包含以下内容:

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

您已经用@ApplicationScope注释了这个@Provides方法,它指示Dagger将返回的Context保存在一个组件中——特别是您也用@ApplicationScope注释的组件中。在您对编辑进行更改之前,没有匹配的@ApplicationScope,Dagger给了您该消息。现在您有了一个,Dagger知道将保存的Context实例存储在哪里。

令人困惑的是通常,Dagger不会反对您尚未使用的不合适的绑定,因此在您开始在该范围中使用绑定之前,Dager不会反对您缺少组件范围注释,这可能是在您引入Fragment范围的同时发生的情况。

另请参阅dagger用户指南:

由于Dagger 2将图中的作用域实例与组件实现的实例相关联,因此组件本身需要声明它们想要表示的作用域。例如,在同一个组件中具有@Singleton绑定和@RequestScoped绑定是没有任何意义的,因为这些作用域具有不同的生命周期,因此必须存在于具有不同生命周期的组件中。要声明组件与给定的作用域相关联,只需将作用域注释应用于组件接口即可。

值得注意的是,由于应用程序的实例在组件的生存期内也不会更改,并且getApplicationContext的值预计不会在应用程序的生存期中更改。这意味着,除了避免在ApplicationContextModule中重复调用您的getApplicationContext方法之外,您的作用域实际上并没有给您带来太多好处。


";但是等等;我听到你在想"为什么Dagger不知道我的@ApplicationScoped绑定属于我的ApplicationComponent?毕竟,Dagger看到ApplicationContextModule安装在ApplicationComponent上,所以唯一有意义的方法是如果ApplicationComponent是隐式@ApplicationScoped"两个原因:首先,从某种意义上说,这是强制性的文档,也有助于Dagger更清楚哪个绑定是错误的,这样你就不会意外地直接在ApplicationComponent中安装@ActivityScoped绑定,并让Dagger相信你的组件同时是应用程序范围和活动范围的。其次,您还可以用作用域注释来注释可注入类,Dagger将无法推断任何内容,因为它没有可以读取的组件-安装-模块关系。在这两者之间,Dagger迫使您在文档中对组件进行注释,我在上面引用了这一点。

我也遇到了同样的问题,但在从ApplicationComponent中删除了提供上下文的模块后,问题就消失了。

我的问题是我使用了@Singleton符号

@Provides
@Singleton
fun provideInstagramApiService(retrofit: Retrofit): InstagramApiService =
retrofit.create(InstagramApiService::class.java)

去除它后,一切都在完美的

@Provides
fun provideInstagramApiService(retrofit: Retrofit): InstagramApiService =
retrofit.create(InstagramApiService::class.java)

最新更新