简体   繁体   中英

Dagger 2 Unable to install module via contributesAndroidInjector for fragment

I'm trying to figure out why I am unable to install a module into my fragment subcomponent via @ContributesAndroidInjector . For instance:

The following works (compiles and is properly injected),

@Module(includes = ColumnWidthModule.class)  
public abstract class GalleryFragmentModule
{
    @ContributesAndroidInjector
    abstract GalleryFragment bindGalleryFragment();
}

but the following does not compile:

@Module  
public abstract class GalleryFragmentModule
{
    @ContributesAndroidInjector(modules = ColumnWidthModule.class)
    abstract GalleryFragment bindGalleryFragment();
}

The compiler error I'm getting is this:

AppComponent.java:24: error: [Dagger/MissingBinding] @javax.inject.Named("columnWidth") java.lang.Integer cannot be provided 
without an @Provides-annotated method.

UPDATE: Here is the full error:

error: [Dagger/MissingBinding] @javax.inject.Named("columnWidth") java.lang.Integer cannot be provided without an @Provides-annotated method.
public interface AppComponent
   ^
A binding with matching key exists in component: GalleryFragmentModule_BindGalleryFragment.GalleryFragmentSubcomponent
  @javax.inject.Named("columnWidth") java.lang.Integer is injected at
      GalleryFragment.columnWidth
  javax.inject.Provider<GalleryFragment> is injected at
      GalleryActivity.galleryFragmentProvider GalleryActivity is injected at
      dagger.android.AndroidInjector.inject(T) [AppComponent → ActivityBindingModule_BindGalleryActivity.GalleryActivitySubcomponent]
  It is also requested at: GalleryFragment.AutoFitGridLayoutManager(…, columnWidth)
  The following other entry points also depend on it:
  dagger.android.AndroidInjector.inject(T) [AppComponent → ActivityBindingModule_BindGalleryActivity.GalleryActivitySubcomponent → GalleryFragmentModule_BindGalleryFragment.GalleryFragmentSubcomponent]
1 error

The module itself looks like this:

@Module
public class ColumnWidthModule
{
    @Provides
    @Named("columnWidth")
    static int columnWidth()
    {
        return 300;
    }
}

and here is where I inject the variable:

public class GalleryFragment extends Fragment
{
    @Inject
    @Named("columnWidth")
    int columnWidth;

    @Override
    public void onAttach(Context context)
    {
        AndroidSupportInjection.inject(this); 
        super.onAttach(context);
    }

    // rest of code not shown 
}

Any help would be appreciated.

I was able to fix this one of two ways:


  1. I noticed that my activity injects a provider for my fragment, like so:

     public class GalleryActivity extends AppCompatActivity implements HasSupportFragmentInjector { @Inject DispatchingAndroidInjector<Fragment> fragmentInjector; @Inject Provider<GalleryFragment> galleryFragmentProvider; @Override protected void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); // ... getSupportFragmentManager() .beginTransaction() .add(R.id.fragment_container, galleryFragmentProvider.get(), null) .commit(); } } 

    The GalleryActivity has a Provider<GalleryFragment> , which means that it is also dependent on columnWidth . In other words, columnWidth is a dependency of GalleryFragment , and GalleryFragment in turn is a dependency of GalleryActivity . Removing the galleryFragmentProvider and changing the fragment transaction to just use a new GalleryFragment() will fix this:

      getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, new GalleryFragment(), null).commit(); 

  1. Another way to fix this and continue using the Provider<GalleryFragment> in the activity is to install the ColumnWidthModule to the activity's contributesAndroidInjector instead, namely this:

     public abstract class ActivityBindingModule { @ActivityScope @ContributesAndroidInjector(modules = { GalleryFragmentModule.class, ColumnWidthModule.class }) abstract GalleryActivity bindGalleryActivity(); } 

    I guess the reason why it worked is because it's pretty much equivalent to what I posted above:

     @Module(includes = ColumnWidthModule.class) public abstract class GalleryFragmentModule { @ContributesAndroidInjector abstract GalleryFragment bindGalleryFragment(); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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