我已经按照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找到
你的片段可能不应该有@ActivityScoped
作为范围。进一步不要使用构造函数注入片段(或任何其他框架类型)!在某些情况下,Android框架会创建这些对象,您最终会在类中使用错误的引用。通过其构建器将片段添加到相应的组件。
您还使用了提供注释的方法以及构造函数注入(@Inject constructor()
)。选一个。既然你也在ArtistAdapter
中使用场注入,你会遇到的下一个“错误”就是null
callback because you don't inject the adapter。你只需创建对象。
通常应该优先考虑构造函数注入,这也将注入字段。完全删除以下内容,在construcor上保留注释:
@Provides
fun provideArtistAdapter() = ArtistAdapter()
继续前进,你的错误起源于MainActivitySubcomponent
(最后一行),似乎是因为你的MainFragment
被绑定为ArtistClickCallback
,但需要一个需要ArtistAdapter
的ArtistClickCallback
...因此你的依赖循环。
一旦你修复了上面提到的问题(在这种情况下就片段上的@Inject
构造函数),这个问题应该自行解决,因为它来自MainFragment
中由Dagger构建的MainActivitySubcomponent
,这是错误的地方,因为你的片段应该有一个较低的范围比活动。
此外,您需要将绑定(@Binds fun bindArtistClickCallback
)移动到MainFragmentModule
中,因为在Activity组件中没有要绑定的片段(当前添加绑定的位置)
解决所有这些问题后,您将片段绑定到正确的FragmentSubcomponent,然后将其绑定为Callback,然后您可以使用它创建适配器,它应该可以工作。
我建议您对Dagger有更全面的了解,并确保了解指出的所有问题/修复。
这应该是它的样子
@FragmentScoped
class MainFragment(): DaggerFragment(), ArtistClickCallback {
@Inject lateinit var adapter : ArtistAdapter
}
@Module
abstract class MainModule {
@FragmentScoped
@ContributesAndroidInjector(modules = [MainFragmentModule::class])
internal abstract fun mainFragment(): MainFragment
}
@Module
class MainFragmentModule {
@Binds
internal abstract fun bindArtistClickCallback(mainFragment: MainFragment) : ArtistClickCallback
}
class ArtistAdapter @Inject constructor(
private val artistClickCallback : ArtistClickCallback
) : PagedListAdapter<LastFmArtist, RecyclerView.ViewHolder>(POST_COMPARATOR)