【发布时间】:2018-11-19 17:25:39
【问题描述】:
我在我的项目中使用Dagger 2 进行依赖注入
问题是当我尝试在依赖于FragmentManager 的片段类中注入ViewPageAdapter 时,如下所示:
@Inject
lateinit var mainTripsFragmentAdapter: MainTripsFragmentAdapter
我收到以下构建错误:
错误:[dagger.android.AndroidInjector.inject(T)] android.support.v4.app.FragmentManager 不能在没有@Provides-annotated 方法的情况下提供。
公共抽象接口 AppComponent 扩展 dagger.android.AndroidInjector { ^ android.support.v4.app.FragmentManager 在注入 com.example.presenters.main.trips.MainTripsFragmentAdapter.(fragmentManager, ...) com.example.presenters.main.trips.MainTripsFragmentAdapter 被注入 com.example.presenters.main.trips.MainTripsFragment.mainTripsFragmentAdapter com.example.presenters.main.trips.MainTripsFragment 被注入 com.example.presenters.main.MainActivity.tripsFragment com.example.presenters.main.MainActivity 被注入 dagger.android.AndroidInjector.inject(arg0) 组件中存在具有匹配键的绑定:com.example.di.FragmentBuilder_BindMainTripsFragment$app_debug.MainTripsFragmentSubcomponent
我研究了 3 天,阅读了很多文章,但我无法弄清楚问题出在哪里!
相关代码我贴一下,太长见谅
需要PagerAdapter的Fragment:
class MainTripsFragment @Inject constructor() : BaseFragment() {
@Inject
lateinit var mainTripsFragmentAdapter: MainTripsFragmentAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
pager.adapter = mainTripsFragmentAdapter
}
}
基本片段:
abstract class BaseFragment : DaggerFragment() {
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(getLayout(), container, false)
abstract fun getLayout(): Int
}
这里是FragmentPagerAdapter:
class MainTripsFragmentAdapter @Inject constructor(
fragmentManager: FragmentManager,
private val mainCurrentTripsFragment: MainCurrentTripsFragment,
private val mainHistoryTripsFragment: MainHistoryTripsFragment
) : FragmentPagerAdapter(fragmentManager) {
override fun getItem(position: Int) = when (position) {
0 -> mainCurrentTripsFragment
1 -> mainHistoryTripsFragment
else -> mainCurrentTripsFragment
}
override fun getCount() = 2
}
这里是 DI 相关的类:
应用组件:
@Singleton
@Component(modules = [
AndroidInjectionModule::class,
ActivityBuilder::class,
FragmentBuilder::class
])
interface AppComponent : AndroidInjector<DaggerApplication> {
fun inject(app: App)
override fun inject(instance: DaggerApplication)
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: Application): Builder
fun build(): AppComponent
}
}
片段生成器:
@Module
abstract class FragmentBuilder {
@ContributesAndroidInjector
internal abstract fun bindMainHomeFragment(): MainHomeFragment
@Module
internal interface MainTripsFragmentModule {
@Binds
fun bindMainTripsFragment(fragment: MainTripsFragment): Fragment
}
@ContributesAndroidInjector(modules = [FragmentModule::class, MainTripsFragmentModule::class])
internal abstract fun bindMainTripsFragment(): MainTripsFragment
@ContributesAndroidInjector
internal abstract fun bindMainCurrentTripsFragment(): MainCurrentTripsFragment
@ContributesAndroidInjector
internal abstract fun bindMainHistoryTripsFragment(): MainHistoryTripsFragment
}
片段模块:
@Module
class FragmentModule {
@Provides
fun provideFragmentManager(fragment: Fragment) = fragment.childFragmentManager
}
ActivityBuilder:
@Module
abstract class ActivityBuilder {
@ContributesAndroidInjector
internal abstract fun contributeMainActivity(): MainActivity
}
主活动:
class MainActivity : BaseActivity() {
@Inject
lateinit var tripsFragment: MainTripsFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
showFragment(tripsFragment)
}
private fun showFragment(fragment: Fragment) {
supportFragmentManager
.beginTransaction()
.replace(R.id.layout_container, fragment)
.commit()
}
}
基础活动:
@SuppressLint("Registered")
abstract class BaseActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
}
override fun supportFragmentInjector() = fragmentInjector
}
应用类:
class App : Application(), HasActivityInjector {
@Inject
lateinit var activityInjector: DispatchingAndroidInjector<Activity>
override fun activityInjector(): AndroidInjector<Activity> = activityInjector
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder()
.application(this)
.build()
.apply {
inject(this@App)
}
}
}
有一点是,如果我在我的活动中@Inject PagerAdapter(我也应该为它添加一个模块)它工作正常。
哪一部分是实施错误的?
【问题讨论】:
-
我以老式的方式使用 dagger 2,但是您在哪里提供 MainTripsFragmentAdapter 在您的模块中?
-
如果您查看错误,您可以在底部看到问题是您尝试在您的
MainActivity中注入tripsFragment。这是错误的范围,您的 mainActivity 组件无法访问您的 FragmentSubComponents 图(与匹配键的绑定存在于组件中试图告诉您) -
@Debanjan 我没有在任何地方提供它,但我注入了构造函数,所以我认为 dagger 将满足它的依赖项
-
@DavidMedenjak 因为我是 dagger2 和 DI 的初学者,所以我无法真正理解范围是如何相互关联的。你能告诉我这是一种解决方法还是我做错了
标签: android dependency-injection kotlin dagger-2