android - 错误 : [Dagger/IncompatiblyScopedBindings] (unscoped) may not reference scoped bindings:

标签 android dependency-injection dagger-2 dagger

我不明白如何解决这个错误。在尝试将 fragment 添加到我的应用程序并使用 Dagger for 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 类:
@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 添加到我的组件来解决这个问题。为什么我必须这样做?在将 fragment 和@FragmentScope 添加到我的代码之前(在此之前我只有@activityscope 和@applicationscope)我没有这个问题,它只是在添加 fragment 后才出现?如果有人可以帮助回答这个问题,那么仍然值得接受这个答案来帮助任何可能有这个问题并想要理解它的人。

最佳答案

您尚未向我们展示 ApplicationContextModule,但从您的错误消息中可能包含以下内容:

@Provides @ApplicationContext @ApplicationScope
Context getApplicationContext(MyApplication application) {
  return application.getApplicationContext();
}
您已注释此 @Provides使用 @ApplicationScope 的方法,它指示 Dagger 将返回的 Context 保存在一个组件中——具体来说,您还使用 @ApplicationScope 注释的组件.在您对编辑进行更改之前,没有匹配的 @ApplicationScope , Dagger 给了你这个信息。现在你有了一个,Dagger 知道在哪里存储保存的 Context 实例。
令人困惑的是,Dagger 不会反对您尚未使用的不适当的绑定(bind),因此在您开始在该范围内使用绑定(bind)之前,Dagger 不会反对您缺少组件范围注释,这可能发生在同一范围内您介绍 Fragment 范围的时间。
另见Dagger User's Guide :

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 的生命周期内发生变化。这意味着除了避免重复调用您的 getApplicationContext 之外,您的范围并没有真正给您太多帮助。 ApplicationContextModule 中的方法。

“但是等等,”我听到你的想法。 “为什么 Dagger 不知道我的 @ApplicationScoped 绑定(bind)属于我的 ApplicationComponent?毕竟,Dagger 看到 ApplicationContextModule 安装在 ApplicationComponent 上,所以唯一有意义的方法是 ApplicationComponent 是隐式的 @ApplicationScoped 。”两个原因:首先,从某种意义上说,这是强制文档,它也有助于 Dagger 更清楚哪个绑定(bind)是错误的,因此您不会意外安装 @ActivityScoped直接绑定(bind)到您的 ApplicationComponent 中,并让 Dagger 相信您的组件同时是应用程序范围和 Activity 范围的。其次,您还可以使用范围注释来注释可注入(inject)类,而 Dagger 将无法推断出任何东西,因为它没有可以读取的组件-安装-模块关系。在这两者之间,Dagger 强制你在文档中注释你的组件,我在上面引用过。

关于android - 错误 : [Dagger/IncompatiblyScopedBindings] (unscoped) may not reference scoped bindings:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53876311/

相关文章:

java - 从 Intent 获取额外内容时出现空指针异常?

android - Retrofit2 如何将/放在动态 baseUrl 的末尾?

java - Android: fragment 生命周期中的方法

gwt - MVP GWT - 注入(inject) EventBus 的问题

laravel - 我如何做类型提示 'automatic injection' 自定义类 laravel

去和 Gin : Passing around struct for database context?

android - Dagger 2.15 - 如何在 Application 类中注入(inject)依赖项

java - 如何连接到特定的 wifi 网络?

java - 错误 : [Dagger/MissingBinding] when trying building the project

android - Dagger 2 - 模块为单例提供