我正在尝试在Android应用中从Dagger 2.7升级到Dagger 2.21。到目前为止,这主要涉及向子组件添加新的作用域,因为这在Dagger 2.8+中得到了实施,但在Dagger 2.7中却没有。我因一个错误被困了几个小时,我希望有人可以帮助我过去。错误是这样的:
error: [Dagger/MissingBinding] com.experticity.android.member.model.card.survey.SurveyCampaign cannot be provided without an @Inject constructor or an @Provides-annotated method.
尽管我在模块中有一个@Provides
方法:
@Module
class SurveyPlayerModule(private val surveyCampaign: SurveyCampaign) {
@Provides
@FragmentScope
fun provideSurveyCampaign(): SurveyCampaign {
return surveyCampaign
}
}
我从片段中提供了SurveyCampaign:
getComponent().surveyPlayerFragmentComponent(
new SurveyPlayerModule(mSurveyCampaign), new FragmentModule(this));
似乎无法获得调查广告系列的类是SurveyTracker
,其构造函数如下所示:
@Inject
public SurveyTracker(UserRepository userRepository, CampaignRepository campaignRepository, SurveyCampaign surveyCampaign) {// Set all of the fields from the constructor parameters}
是的,我们的项目是Kotlin和Java的混合,逐渐向越来越多的Kotlin过渡。
错误消息的其余部分,为简洁起见,已删除软件包名称:
SurveyCampaign is injected at SurveyTracker(…, surveyCampaign)
SurveyTracker is provided at SurveyPlayerFragmentComponent.surveyTracker() [ApplicationComponent → SessionComponent → RepositoryComponent → activity.ActivityComponent → activity.SurveyPlayerFragmentComponent]
The following other entry points also depend on it:
SurveyPlayerFragmentComponent.inject(SurveyPlayerViewModel) [ApplicationComponent → SessionComponent → RepositoryComponent → activity.ActivityComponent → activity.SurveyPlayerFragmentComponent]
SurveyPlayerFragmentComponent.inject(SurveyQuestionViewModel) [ApplicationComponent → SessionComponent → RepositoryComponent → activity.ActivityComponent → activity.SurveyPlayerFragmentComponent]
SurveyPlayerFragmentComponent.inject(SurveyCompletedViewModel) [ApplicationComponent → SessionComponent → RepositoryComponent → activity.ActivityComponent → activity.SurveyPlayerFragmentComponent]
完整的,未编辑的错误堆栈:
ApplicationComponent.java:11: error: [Dagger/MissingBinding] com.experticity.android.member.model.card.survey.SurveyCampaign cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface ApplicationComponent {
^
com.experticity.android.member.model.card.survey.SurveyCampaign is injected at
com.experticity.android.member.domain.SurveyTracker(…, surveyCampaign)
com.experticity.android.member.domain.SurveyTracker is injected at
com.experticity.android.member.ui.viewmodel.SurveyPlayerViewModel.mSurveyTracker
com.experticity.android.member.ui.viewmodel.SurveyPlayerViewModel is injected at
com.experticity.android.member.injection.component.activity.SurveyPlayerFragmentComponent.inject(com.experticity.android.member.ui.viewmodel.SurveyPlayerViewModel) [com.experticity.android.member.injection.component.ApplicationComponent → com.experticity.android.member.injection.component.SessionComponent → com.experticity.android.member.injection.component.RepositoryComponent → com.experticity.android.member.injection.component.activity.ActivityComponent → com.experticity.android.member.injection.component.activity.SurveyPlayerFragmentComponent]
The following other entry points also depend on it:
com.experticity.android.member.injection.component.activity.SurveyPlayerFragmentComponent.inject(com.experticity.android.member.ui.viewmodel.SurveyQuestionViewModel) [com.experticity.android.member.injection.component.ApplicationComponent → com.experticity.android.member.injection.component.SessionComponent → com.experticity.android.member.injection.component.RepositoryComponent → com.experticity.android.member.injection.component.activity.ActivityComponent → com.experticity.android.member.injection.component.activity.SurveyPlayerFragmentComponent]
com.experticity.android.member.injection.component.activity.SurveyPlayerFragmentComponent.inject(com.experticity.android.member.ui.viewmodel.SurveyCompletedViewModel) [com.experticity.android.member.injection.component.ApplicationComponent → com.experticity.android.member.injection.component.SessionComponent → com.experticity.android.member.injection.component.RepositoryComponent → com.experticity.android.member.injection.component.activity.ActivityComponent → com.experticity.android.member.injection.component.activity.SurveyPlayerFragmentComponent]
这是组件:
@FragmentScope
@Subcomponent(modules = [SurveyPlayerModule::class, FragmentModule::class])
interface SurveyPlayerFragmentComponent {
@ChildFragmentManager
fun childFragmentManager(): FragmentManager
fun surveyTracker(): SurveyTracker
//Fragments
fun inject(fragment: SurveyPlayerFragment)
// ViewModels
fun inject(viewModel: SurveyPlayerViewModel)
fun inject(viewModel: SurveyQuestionViewModel)
fun inject(viewModel: SurveyCompletedViewModel)
// Adapters
fun inject(adapter: SurveyPlayerAdapter)
}
答案 0 :(得分:1)
我终于明白了。我一直在想:“感觉SurveyTracker
和SurveyPlayerFragment
(实际上是创建模块并将surveyCampaign
传递到模块)不在同一范围内。”我从非Dagger的角度考虑这个问题,但事实证明,SurveyTracker
类是用@ActivityScope
范围注释的,而不是像组件和模块中的其他所有注释那样的@FragmentScope
注释的。将其更改为@FragmentScope
可以修复它。由于某些原因,我没有考虑过检查SurveyTracker
上的注释,因为我不认为这是您可以做的。大卫,谢谢您的帮助。