Car*_*ton 4 android dependency-injection dagger dagger-2
我不明白如何解决这个错误。在尝试将片段添加到我的应用程序并使用 Dagger 进行 DI 后,我收到此错误。这是错误堆栈:
错误:[Dagger/IncompatifiableScopedBindings] di.component.ApplicationComponent (unscoped) 可能不引用作用域绑定:@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)SharedPreferencesHelper, service.KeyStoreService)SharedPreferencesHelper, service.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();
}
Run Code Online (Sandbox Code Playgroud)
我的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激。
编辑:我设法通过将 @ApplicationScope 添加到我的组件来解决这个问题。为什么我必须这样做?在将片段和@FragmentScope 添加到我的代码之前(在此之前我只有@activityscope 和@applicationscope)我没有这个问题,它只在添加片段后出现?如果有人可以帮助回答这个问题,那么接受该答案以帮助其他可能遇到此问题并希望了解它的人仍然值得。
您尚未向我们展示 ApplicationContextModule,但从您的错误消息来看,它可能包含以下内容:
@Provides @ApplicationContext @ApplicationScope
Context getApplicationContext(MyApplication application) {
return application.getApplicationContext();
}
Run Code Online (Sandbox Code Playgroud)
您已使用 注释此@Provides方法@ApplicationScope,这指示 Dagger 将返回的 Context 保存在组件中——特别是,您也已使用 注释的组件@ApplicationScope。在您对编辑进行更改之前,没有匹配的@ApplicationScope,而 Dagger 给了您该消息。现在你有了一个,Dagger 知道在哪里存储保存的 Context 实例。
令人困惑的是,Dagger 不会反对您尚未使用的不适当绑定,因此在您开始在该范围内使用绑定之前,Dagger 不会反对您缺少组件范围注释,这可能发生在相同的范围内当您介绍 Fragment 范围时。
另请参阅Dagger 用户指南:
由于 Dagger 2 将图中的作用域实例与组件实现的实例相关联,因此组件本身需要声明它们打算表示的作用域。例如,在同一个组件中拥有@Singleton 绑定和@RequestScoped 绑定是没有任何意义的,因为这些范围具有不同的生命周期,因此必须存在于具有不同生命周期的组件中。要声明组件与给定范围相关联,只需将范围注释应用于组件接口。
值得注意的是,由于 Application 的实例在组件的生命周期内也不会改变,并且 getApplicationContext 的值预计不会在应用程序的生命周期内改变。这意味着除了避免重复调用ApplicationContextModule 中的 getApplicationContext方法之外,您的范围并没有真正为您提供多少。
“但是等等,”我听到你在想。“为什么 Dagger 不知道我的@ApplicationScoped绑定属于我的 ApplicationComponent?毕竟,Dagger 看到 ApplicationContextModule 安装在 ApplicationComponent 上,所以唯一有意义的方法是 ApplicationComponent 是隐式的@ApplicationScoped。” 两个原因:首先,从某种意义上说,这是强制文档,也有助于 Dagger 更清楚哪个绑定是错误的,因此您不会意外安装@ActivityScoped直接绑定到您的 ApplicationComponent 中,并让 Dagger 相信您的 Component 同时是应用程序范围和活动范围的。其次,您还可以使用范围注释来注释一个可注入类,而 Dagger 将无法推断任何内容,因为它没有可以读取的组件-安装-模块关系。在这两者之间,Dagger 强制您在文档中注释您的组件,我在上面引用过。
| 归档时间: |
|
| 查看次数: |
5126 次 |
| 最近记录: |