Dagger 2无法通过贡献AndroidInjector安装模块以获取片段

时间:2018-11-18 02:45:16

标签: android dependency-injection dagger-2

我试图弄清楚为什么我无法通过@ContributesAndroidInjector将模块安装到片段子组件中。例如:

以下工作原理(已编译并正确注入),

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

,但以下内容无法编译:

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

我得到的编译器错误是:

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

模块本身如下所示:

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

,这是我注入变量的地方:

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 
}

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我能够通过以下两种方法之一解决此问题:


  1. 我注意到我的活动为我的片段注入了一个提供程序,就像这样:

    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();
    
        }
    }
    

    GalleryActivity有一个Provider<GalleryFragment>,这意味着它也依赖于columnWidth。换句话说,columnWidthGalleryFragment的依赖项,而GalleryFragment则是GalleryActivity的依赖项。删除galleryFragmentProvider并将片段事务更改为仅使用new GalleryFragment()将解决此问题:

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

  1. 解决此问题并继续在活动中继续使用Provider<GalleryFragment>的另一种方法是将ColumnWidthModule安装到活动的contributesAndroidInjector上,即:

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

    我猜它起作用的原因是因为它与我上面发布的内容相当等效:

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