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:
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();
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.