android 错误:[Dagger/IncompatiblyScopedBindings](unscoped)可能无法引用有作用域的绑定:

ar7v8xwq  于 2023-04-10  发布在  Android
关注(0)|答案(3)|浏览(208)

我不知道如何解决这个错误。我在尝试向应用程序添加片段并使用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.应用范围存储库.SharedPreferencesHelper di.Module. SharedPreferencesHelperModule.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注解。它只是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设法解决了这个问题。为什么我必须这样做?在将fragments和@FragmentScope添加到我的代码之前(在此之前我只有@activityscope和@applicationscope)我没有这个问题,只是在添加片段后才出现的吗?如果有人能帮助回答这个问题接受这个答案仍然是值得,以帮助其他可能有这个问题并希望理解它的人。

2ul0zpep

2ul0zpep1#

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

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

您已经使用@ApplicationScope注解了这个@Provides方法,它指示Dagger将返回的Context保存在一个Component中-具体地说,就是您也使用@ApplicationScope注解的那个组件。在您在编辑中进行更改之前,没有匹配的@ApplicationScope,Dagger给了您这个消息。现在您有了一个,Dagger知道在哪里存储保存的Context示例。
令人困惑的是,Dagger不会反对你还没有使用的不合适的绑定,所以Dagger不会反对你缺乏组件作用域注解,直到你开始在该作用域中使用绑定,这可能是在你引入Fragment作用域的同时发生的。
参见Dagger用户指南:
由于Dagger 2将图中的作用域示例与组件实现的示例相关联,因此组件本身需要声明它们打算表示哪个作用域。在同一个组件中有一个@Singleton绑定和一个@RequestScoped绑定没有任何意义,因为这些作用域有不同的生命周期,因此必须存在于具有不同生命周期的组件中。要声明一个组件与给定的作用域相关联,只需将作用域注解应用于组件接口。
值得注意的是,由于Application的示例在组件的生命周期内也不会改变,并且getApplicationContext的值在Application的生命周期内也不会改变。这意味着你的作用域并没有给你带来太多,除了避免在ApplicationContextModule中重复调用 yourgetApplicationContext方法。
“等等,”我听到你在想,“为什么Dagger不知道我的@ApplicationScoped绑定属于我的ApplicationComponent?毕竟,Dagger看到ApplicationContextModule安装在ApplicationComponent上,所以唯一有意义的方法是ApplicationComponent是否隐式地为@ApplicationScoped。”两个原因:首先,从某种意义上说,这是强制文档,也有助于Dagger更清楚地了解哪个绑定是错误的,这样你就不会意外地直接在ApplicationComponent中安装@ActivityScoped绑定,并说服Dagger你的Component同时是应用程序范围和活动范围的。而Dagger无法推断出任何东西,因为它无法读取组件-安装-模块之间的关系。在这两者之间,Dagger强迫你在文档中注解你的组件,我在上面引用过。

xxb16uws

xxb16uws2#

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

9o685dep

9o685dep3#

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

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

移除后,一切都运行得很完美

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

相关问题