error: [Dagger/IncompatiblyScopedBindings] (unscoped) may not reference scoped bindings:
error: [Dagger/IncompatiblyScopedBindings] (unscoped) may not reference scoped bindings:
我不明白如何解决这个错误。尝试将片段添加到我的应用程序并使用 Dagger 进行 DI 后出现此错误。这是错误堆栈:
error: [Dagger/IncompatiblyScopedBindings]
di.component.ApplicationComponent (unscoped) may not reference scoped
bindings: @Provides @di.ApplicationContext @di.ApplicationScope
android.content.Context
di.Module.ApplicationContextModule.getApplicationContext(application.MyApplication)
@Provides @di.ApplicationScope android.content.SharedPreferences
di.Module.SharedPreferencesModule.getSharedPreferences(@di.ApplicationContext
android.content.Context) @Provides @di.ApplicationScope
service.KeyStoreServiceInterface
di.Module.KeyStoreModule.getKeyStoreService(@Named("KEY_STORE_FILE")
java.io.File) @Provides @di.ApplicationScope
repository.SharedPreferencesHelper
di.Module.SharedPreferenceHelperModule.getSharedPreferencesHelper()
@Provides @di.ApplicationScope service.CoinmarketcapService
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
di.Module.WalletRepositoryModule.getWalletRepository(repository.SharedPreferencesHelper,
service.KeyStoreService)
这是我的 ApplicationComponent class:
@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 注释。它只是带有 Retention.RUNTIME 的 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 将返回的上下文保存在组件中——具体来说,您还使用 [=12= 注释的组件].在您对编辑进行更改之前,没有匹配的 @ApplicationScope
,Dagger 给了您该消息。现在你有了一个,Dagger 知道在哪里存储保存的 Context 实例。
令人困惑 慷慨地,Dagger 不会反对您尚未使用的不适当的绑定,因此 Dagger 不会反对您缺少组件范围注释,直到您开始在该范围内使用绑定,这可能是在您引入 Fragment 范围的同时发生的。
Since Dagger 2 associates scoped instances in the graph with instances of component implementations, the components themselves need to declare which scope they intend to represent. For example, it wouldn’t make any sense to have a @Singleton binding and a @RequestScoped binding in the same component because those scopes have different lifecycles and thus must live in components with different lifecycles. To declare that a component is associated with a given scope, simply apply the scope annotation to the component interface.
值得注意的是,由于 Application 的实例在组件的生命周期内也不会发生变化,并且 getApplicationContext 的值预计不会在 Application 的生命周期内发生变化。这意味着除了避免重复调用 ApplicationContextModule 中的 your getApplicationContext
方法之外,您的作用域并没有真正给您带来太多帮助。
“但是等等,”我听到你在想。 “为什么 Dagger 不知道 我的 @ApplicationScoped
绑定属于我的 ApplicationComponent?毕竟,Dagger 看到 ApplicationContextModule 安装在 ApplicationComponent 上,所以唯一有意义的方法是如果 ApplicationComponent隐式 @ApplicationScoped
。”两个原因:首先,从某种意义上说,这是强制文档,它还可以帮助 Dagger 更清楚哪个绑定是错误的,这样你就不会不小心直接在你的 ApplicationComponent 中安装 @ActivityScoped
绑定并说服 Dagger 你的组件是同时应用程序范围和 activity 范围。其次,您还可以使用范围注释来注释可注入的 class,Dagger 将无法推断出任何内容,因为没有它可以读取的组件-安装-模块关系。在这两者之间,Dagger 强制您在文档中注释您的组件,我在上面引用过。
我有同样的问题,但是从 ApplicationComponent 中删除提供上下文的模块后问题就消失了。
我不明白如何解决这个错误。尝试将片段添加到我的应用程序并使用 Dagger 进行 DI 后出现此错误。这是错误堆栈:
error: [Dagger/IncompatiblyScopedBindings] di.component.ApplicationComponent (unscoped) may not reference scoped bindings: @Provides @di.ApplicationContext @di.ApplicationScope android.content.Context di.Module.ApplicationContextModule.getApplicationContext(application.MyApplication) @Provides @di.ApplicationScope android.content.SharedPreferences di.Module.SharedPreferencesModule.getSharedPreferences(@di.ApplicationContext android.content.Context) @Provides @di.ApplicationScope service.KeyStoreServiceInterface di.Module.KeyStoreModule.getKeyStoreService(@Named("KEY_STORE_FILE") java.io.File) @Provides @di.ApplicationScope repository.SharedPreferencesHelper di.Module.SharedPreferenceHelperModule.getSharedPreferencesHelper() @Provides @di.ApplicationScope service.CoinmarketcapService 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 di.Module.WalletRepositoryModule.getWalletRepository(repository.SharedPreferencesHelper, service.KeyStoreService)
这是我的 ApplicationComponent class:
@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 注释。它只是带有 Retention.RUNTIME 的 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 将返回的上下文保存在组件中——具体来说,您还使用 [=12= 注释的组件].在您对编辑进行更改之前,没有匹配的 @ApplicationScope
,Dagger 给了您该消息。现在你有了一个,Dagger 知道在哪里存储保存的 Context 实例。
令人困惑 慷慨地,Dagger 不会反对您尚未使用的不适当的绑定,因此 Dagger 不会反对您缺少组件范围注释,直到您开始在该范围内使用绑定,这可能是在您引入 Fragment 范围的同时发生的。
Since Dagger 2 associates scoped instances in the graph with instances of component implementations, the components themselves need to declare which scope they intend to represent. For example, it wouldn’t make any sense to have a @Singleton binding and a @RequestScoped binding in the same component because those scopes have different lifecycles and thus must live in components with different lifecycles. To declare that a component is associated with a given scope, simply apply the scope annotation to the component interface.
值得注意的是,由于 Application 的实例在组件的生命周期内也不会发生变化,并且 getApplicationContext 的值预计不会在 Application 的生命周期内发生变化。这意味着除了避免重复调用 ApplicationContextModule 中的 your getApplicationContext
方法之外,您的作用域并没有真正给您带来太多帮助。
“但是等等,”我听到你在想。 “为什么 Dagger 不知道 我的 @ApplicationScoped
绑定属于我的 ApplicationComponent?毕竟,Dagger 看到 ApplicationContextModule 安装在 ApplicationComponent 上,所以唯一有意义的方法是如果 ApplicationComponent隐式 @ApplicationScoped
。”两个原因:首先,从某种意义上说,这是强制文档,它还可以帮助 Dagger 更清楚哪个绑定是错误的,这样你就不会不小心直接在你的 ApplicationComponent 中安装 @ActivityScoped
绑定并说服 Dagger 你的组件是同时应用程序范围和 activity 范围。其次,您还可以使用范围注释来注释可注入的 class,Dagger 将无法推断出任何内容,因为没有它可以读取的组件-安装-模块关系。在这两者之间,Dagger 强制您在文档中注释您的组件,我在上面引用过。
我有同样的问题,但是从 ApplicationComponent 中删除提供上下文的模块后问题就消失了。