简体   繁体   English

组件中存在具有匹配键的绑定:dagger 2.12

[英]A binding with matching key exists in component : dagger 2.12

i'm Using the Dagger 2.12.我正在使用 Dagger 2.12。 i have three activity in my application: Splash, Login, Main;我的应用程序中有三个活动:Splash、Login、Main; Splash Activity has little code so i did not add this to dagger graph. Splash Activity 的代码很少,所以我没有将它添加到匕首图中。 i have two fragment 'Login Fragment' and 'AddressManager Fragment' that want to have these fragments in my activities(Login and Main) .我有两个片段“登录片段”和“地址管理器片段”,它们希望在我的活动(登录和主)中有这些片段。 i don't want to use @ContributesAndroidInjector because of some reasons and get this error:由于某些原因,我不想使用@ContributesAndroidInjector并收到此错误:

public interface AppComponent {
       ^
   ir.sabaap.jahadattendancesystem.di.component.LoginFragmentComponent.Builder is injected at
   ir.sabaap.jahadattendancesystem.di.module.FragmentBuilder.bindLoginFragment(builder)
   java.util.Map<java.lang.Class<? extends androidx.fragment.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends androidx.fragment.app.Fragment>>> is injected at
   dagger.android.DispatchingAndroidInjector.<init>(injectorFactories)
   dagger.android.DispatchingAndroidInjector<androidx.fragment.app.Fragment> is injected at
   ir.sabaap.jahadattendancesystem.ui.main.MainActivity.fragmentDispatchingAndroidInjector
   ir.sabaap.jahadattendancesystem.ui.main.MainActivity is injected at
   dagger.android.AndroidInjector.inject(arg0)
   A binding with matching key exists in component: ir.sabaap.jahadattendancesystem.di.component.LoginActivityComponent

what is the problm?问题是什么? :-( :-(

AppComponent.java: AppComponent.java:

 @Singleton
 @Component(modules = {AndroidInjectionModule.class, ActivityBuilder.class, AppModule.class,
    ViewModelFactoryModule.class})
  public interface AppComponent {
       @Component.Builder
       interface Builder {
          @BindsInstance
          Builder application(Application application);
          AppComponent build();
}
   void inject(App app);
}

ActivityBuilder.java: ActivityBuilder.java:

@Module
public abstract class ActivityBuilder {
// main activity
 @Binds
 @IntoMap
 @ActivityKey(MainActivity.class)
 abstract AndroidInjector.Factory<? extends Activity> 
 bindMainActivity(MainActivityComponent.Builder builder);

// login activity
 @Binds
 @IntoMap
 @ActivityKey(LoginActivity.class)
 abstract AndroidInjector.Factory<? extends Activity> 
 bindLoginActivity(LoginActivityComponent.Builder builder);


}

FragmentBuilder.java: FragmentBuilder.java:

 @Module
 public abstract class FragmentBuilder {
   //bind fragments ;
   @Binds
   @IntoMap
   @FragmentKey(BarCodeFragment.class)
   abstract AndroidInjector.Factory<? extends Fragment> bindBarcodeFragment( BarcodeFragmentComponent.Builder builder);

   @Binds
   @IntoMap
   @FragmentKey(AddressManager.class)
   abstract AndroidInjector.Factory<? extends Fragment> bindAddressFragment(AddressManagerFragmentComponent.Builder builder);

   @Binds
   @IntoMap
   @FragmentKey(LoginFragment.class)
   abstract AndroidInjector.Factory<? extends Fragment> bindLoginFragment(LoginFragmentComponent.Builder builder);

   }

LoginFragmentComponent.java: LoginFragmentComponent.java:

 @Subcomponent(modules = {LoginFragmentModule.class , LoginFragmentViewModelModule.class})
 public interface LoginFragmentComponent extends AndroidInjector<LoginFragment> {
   @Subcomponent.Builder
   abstract class Builder extends AndroidInjector.Builder<LoginFragment>{}
 }

LoginActivityComponent.java:登录活动组件.java:

 @Subcomponent(modules = {LoginActivityModule.class, LoginActivityViewModelModule.class, FragmentBuilder.class})
 public interface LoginActivityComponent extends AndroidInjector<LoginActivity> {
   @Subcomponent.Builder
   abstract class Builder extends AndroidInjector.Builder<LoginActivity> {}

} }

AppModule.java: AppModule.java:

 @Module(subcomponents = {MainActivityComponent.class, LoginActivityComponent.class})
 public class AppModule {
   @Singleton
   @Provides
   OkHttpClient.Builder provideOkHttp(HttpLoggingInterceptor interceptor,
                                   PersistentCookieJar persistentCookieJar) {
       final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
       httpClient.connectTimeout(8, TimeUnit.SECONDS);
       httpClient.readTimeout(8, TimeUnit.SECONDS);
       httpClient.callTimeout(8, TimeUnit.SECONDS);
       httpClient.cookieJar(persistentCookieJar);
       httpClient.addInterceptor(interceptor);
       return httpClient;
   }

   ... //other methods 
 }

LoginActivity.java:登录活动.java:

   public class LoginActivity extends BaseActivity implements 
   HasSupportFragmentInjector {
   @Inject
   DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;

   @Inject
   SharedPreferences sharedPreferences;

   @Override
   public void onCreate(@Nullable Bundle savedInstanceState) {
    AndroidInjection.inject(this);
    ((App) getApplication()).setActivity(this);
    super.onCreate(savedInstanceState);
   }

   @Override
   protected int getContentView() {
       return R.layout.content_main;
   }

   @Override
   protected boolean requestFullScreenActivity() {
       return true;
   }

   @Override
   protected void init() {

       setLocalDirection();

       boolean address_def = sharedPreferences.getBoolean("address_def", false);

       if (address_def)
           attachFragment(new LoginFragment());
       else
           attachFragment(new AddressManager());

   }

   @Override
   protected int toolbarMenu() {
       return 0;
   }

   public void attachFragment(Fragment fragment) {
       FragmentTransaction transaction = 
  getSupportFragmentManager().beginTransaction();
       transaction.replace(R.id.nav_host_fragment, fragment);
       transaction.commit();
   }

   @Override
   public void setLocalDirection() {

   }

   @Override
   public DispatchingAndroidInjector<Fragment> 
   supportFragmentInjector() {
       return fragmentDispatchingAndroidInjector;
   }

} }

Maybe it is just omitted from the question, but is the Fragment subcomponent LoginFragmentComponent declared under one @Module(subcomponent =...) of MainActivityComponent ?也许它只是从问题中省略了,但是 Fragment 子组件LoginFragmentComponent是在MainActivityComponent的一个@Module(subcomponent =...)下声明的吗?

The info A binding with matching key exists in component is saying that LoginFragmentComponent.Builder can be provided in LoginActivityComponent , but not in both AppComponent alone nor MainActivity . info A binding with matching key exists in component表示LoginFragmentComponent.Builder可以在LoginActivityComponent中提供,但不能在AppComponent单独或MainActivity中提供。

The guide of Dagger-Android suggests listing the @Module.subcomponents in the same module that declares the @Binds @IntoMap @ClassKey(...) method: Dagger-Android 的指南建议在声明@Binds @IntoMap @ClassKey(...)方法的同一模块中列出@Module.subcomponents

@Module(subcomponents = YourActivitySubcomponent.class)
abstract class YourActivityModule {
  @Binds
  @IntoMap
  @ClassKey(YourActivity.class)
  abstract AndroidInjector.Factory<?>
      bindYourAndroidInjectorFactory(YourActivitySubcomponent.Factory factory);
}

@Module(subcomponents = YourFragmentSubcomponent.class)
abstract class YourFragmentModule {
  @Binds
  @IntoMap
  @ClassKey(YourFragment.class)
  abstract AndroidInjector.Factory<?>
      bindYourFragmentInjectorFactory(YourFragmentSubcomponent.Factory factory);
}

For your case, add @Module(subcomponents =...) inside both ActivityBuilder and FragmentBuilder modules to make sure that they are never forgotten.对于您的情况,在ActivityBuilderFragmentBuilder模块中添加@Module(subcomponents =...)以确保它们永远不会被遗忘。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM