使用Dagger2将Adapter类注入Fragment

时间:2019-02-27 18:59:44

标签: android dagger-2

我已遵循Android体系结构蓝图Dagger2进行依赖项注入:URL

现在我想将Adapter插入我的Fragment类:

@ActivityScoped
class MainFragment @Inject
constructor(): DaggerFragment(), ArtistClickCallback {

    @Inject lateinit var adapter : ArtistAdapter 
}

主模块类:

@Module
abstract class MainModule {
    @FragmentScoped
    @ContributesAndroidInjector(modules = [MainFragmentModule::class])
    internal abstract fun mainFragment(): MainFragment

    @Binds
    internal abstract fun bindArtistClickCallback(mainFragment: MainFragment) : ArtistClickCallback
}

MainFragmentModule:

@Module
class MainFragmentModule {

    @Provides
    fun provideArtistAdapter() = ArtistAdapter()
}

这是我的适配器类:

 class ArtistAdapter @Inject constructor(
  private val artistClickCallback : ArtistClickCallback
) : PagedListAdapter<LastFmArtist, RecyclerView.ViewHolder>(POST_COMPARATOR)

构建项目时,出现以下Kotlin编译器错误:

error: [Dagger/DependencyCycle] Found a dependency cycle:
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.sample.android.lastfm.LastFmApp> {
                ^
      com.sample.android.lastfm.ui.main.MainFragment is injected at


com.sample.android.lastfm.ui.main.MainModule.bindArtistClickCallback$app_debug(mainFragment)
  com.sample.android.lastfm.ArtistClickCallback is injected at
      com.sample.android.lastfm.ui.main.ArtistAdapter.artistClickCallback
  com.sample.android.lastfm.ui.main.ArtistAdapter is injected at
      com.sample.android.lastfm.ui.main.MainFragment.adapter
  com.sample.android.lastfm.ui.main.MainFragment is injected at
      com.sample.android.lastfm.ui.main.MainActivity.mainFragment
  com.sample.android.lastfm.ui.main.MainActivity is injected at
      dagger.android.AndroidInjector.inject(T) [com.sample.android.lastfm.di.AppComponent → com.sample.android.lastfm.di.ActivityBindingModule_MainActivity$app_debug.MainActivitySubcomponent]

您能建议我如何解决这个问题吗?

代码位于URL

1 个答案:

答案 0 :(得分:0)

您的片段可能不是@ActivityScoped作为范围。此外,不要将构造函数注入与片段(或任何其他框架类型)一起使用!在某些情况下,Android框架会创建这些对象,并且您最终在类中将获得错误的引用。通过其生成器将片段添加到相应的组件中。

您还使用了提供注释的方法以及构造函数注入(@Inject constructor())。选择一个。由于您还在ArtistAdapter 中使用字段注入,因此下一个“错误”将在任何地方出现null callback because you don't inject the adapter。您只需创建对象。
通常应该赞成构造方法注入,这也将注入字段。完全删除以下 ,将注释保留在构造上:

@Provides
fun provideArtistAdapter() = ArtistAdapter()

继续,您的错误起源于MainActivitySubcomponent(最后一行),似乎是因为您的MainFragment被绑定为ArtistClickCallback,但是需要一个ArtistAdapter ArtistClickCallback ...因此,您的依赖关系周期就会出现。

一旦您解决了上面提到的问题(在这种情况下为片段上的@Inject构造器),此问题便会自行解决,因为它起源于{{1}中由Dagger构造的MainFragment },无论如何这都是错误的地方,因为您的片段的作用域应该比活动的作用域小。

此外,您还需要将绑定(MainActivitySubcomponent)移到@Binds fun bindArtistClickCallback中,因为在Activity组件(当前在其中添加绑定)中没有要绑定的片段

修复所有这些问题后,您会将片段绑定到正确的FragmentSubcomponent,在其中将其绑定为回调,然后可以使用它创建适配器,并且适配器应该可以工作。

我建议您对Dagger进行更全面的了解,并确保了解所指出的所有问题/修复程序。


这是它的外观

MainFragmentModule