android.support.v4.app.FragmentManager不能提供@ Provide或@ Produces注解的方法

所以我对Dagger很陌生,试图通过活动加上独立片段和独立导航来“Kotlin”MVP项目的“daggerify”。

事实上,我使用基于支持lib的Fragment的好几个视图让我尝试最近的匕首Android支持function。 经过一些与构件图构建挣扎后,我遇到了这个错误代表的问题:

e: ...\MyApp\app\build\tmp\kapt3\stubs\debug\com\...\di\app\MyAppComponent.java:6: error: [dagger.android.AndroidInjector.inject(T)] android.support.v4.app.FragmentManager cannot be provided without an @Provides- or @Produces-annotated method. e: e: public abstract interface MyAppComponent extends dagger.android.AndroidInjector { e: ^ e: android.support.v4.app.FragmentManager is injected at e: myapp.ui.common.BaseActivity.fragmentManager e: myapp.ui.main.MainActivity is injected at e: dagger.android.AndroidInjector.inject(arg0) e: java.lang.IllegalStateException: failed to analyze: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing at org.jetbrains.kotlin.analyzer.AnalysisResult.throwIfError(AnalysisResult.kt:57) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:137) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:158) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:61) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:107) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:51) at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92) at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:386) at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$2.invoke(CompileServiceImpl.kt:96) at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:892) at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:96) at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137) at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:919) at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:891) at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:385) at sun.reflect.GeneratedMethodAccessor95.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: org.jetbrains.kotlin.kapt3.diagnostic.KaptError: Error while annotation processing at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:90) at org.jetbrains.kotlin.kapt3.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:42) at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:205) at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:166) at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:82) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:96) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:106) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:83) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:376) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:67) at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:96) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:367) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules(KotlinToJVMBytecodeCompiler.kt:132) ... 29 more FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:kaptDebugKotlin'. 

这是一些代码。

应用程序:

 class MyApp : MultiDexApplication(), HasActivityInjector { @Inject @JvmField var activityInjector: DispatchingAndroidInjector? = null override fun onCreate() { super.onCreate() DaggerMyAppComponent.builder().create(this).inject(this) } override fun activityInjector(): AndroidInjector? { return activityInjector } } 

AppComponent:

 @Singleton @Component(modules = [ MyAppModule::class, DataModule::class, PreferencesModule::class, ServiceModule::class ]) interface MyAppComponent : AndroidInjector { @Component.Builder abstract class Builder : AndroidInjector.Builder() } 

的AppModule:

 @Module(includes = [AndroidSupportInjectionModule::class]) abstract class MyAppModule { @Binds @Singleton abstract fun application(myApp: MyApp): Application @PerActivity @ContributesAndroidInjector(modules = [(MainActivityModule::class)]) abstract fun mainActivityInjector(): MainActivity //... other activity injectors } 

BaseActivityModule:

 @Module abstract class BaseActivityModule { @Binds @PerActivity internal abstract fun activity(appCompatActivity: AppCompatActivity): Activity @Binds @PerActivity internal abstract fun activityContext(activity: Activity): Context @Module companion object { const val ACTIVITY_FRAGMENT_MANAGER = "BaseActivityModule.activityFragmentManager" @JvmStatic @Provides @Named(ACTIVITY_FRAGMENT_MANAGER) @PerActivity fun activityFragmentManager(activity: AppCompatActivity): FragmentManager { return activity.supportFragmentManager } } } 

BaseFragmentModule:

 @Module class BaseFragmentModule { @Module companion object { const val FRAGMENT = "BaseFragmentModule.fragment" const val CHILD_FRAGMENT_MANAGER = "BaseFragmentModule.childFragmentManager" @JvmStatic @Provides @Named(CHILD_FRAGMENT_MANAGER) @PerFragment fun childFragmentManager(@Named(FRAGMENT) fragment: Fragment): FragmentManager { return fragment.childFragmentManager } } } 

BaseChildFragmentModule:

 @Module class BaseChildFragmentModule { companion object { const val CHILD_FRAGMENT = "BaseChildFragmentModule.childFragment" } } 

示例MainActivityModule:

 @Module(includes = [ BaseActivityModule::class ]) abstract class MainActivityModule { @Binds @PerActivity abstract fun appCompatActivity(mainActivity: MainActivity): AppCompatActivity @PerFragment @ContributesAndroidInjector(modules = [LocationFragmentModule::class]) abstract fun locationFragmentInjector(): LocationFragment //... other related fragments injection methods } 

我将片段视为独立的视图,因此每个片段都有一个View Module和1 Presenter Module ATM。 以下是片段的DI部分示例:

 @Module(includes = [BaseFragmentModule::class, LocationPresenterModule::class]) abstract class LocationFragmentModule { @Binds @Named(BaseFragmentModule.FRAGMENT) @PerFragment abstract fun fragment(locationFragment: LocationFragment): Fragment @Binds @PerFragment abstract fun locationView(locationFragment: LocationFragment): LocationView } @Module abstract class LocationPresenterModule { @Binds @PerFragment abstract fun locationPresenter(locationPresenterImpl: LocationPresenterImpl): LocationPresenter } 

Gradle匕首依赖关系:

 implementation "com.google.dagger:dagger:$dagger_version" kapt "com.google.dagger:dagger-compiler:$dagger_version" implementation "com.google.dagger:dagger-android:$dagger_version" kapt "com.google.dagger:dagger-android-processor:$dagger_version" implementation "com.google.dagger:dagger-android-support:$dagger_version" kapt "com.google.dagger:dagger-android-support:$dagger_version" 

我试着将AndroidSupportInjectionModule :: class移到主要组件的模块数组中。

我希望这是框架相关的代码生成问题,我只是对支持机制行为有一个不好的理解,因为所有模块的@Provides部分应该已经包含了这个注解。

从MyApp类的代码片断可以看出,目前我坚持扩展MultiDexApplication,所以我不知道这个问题可能与MultiDex支持有关。

这种情况看起来很奇怪,所以我希望有更多经验丰富的匕首用户指向正确的方向。

编辑:

这里是BaseActivity代码:

 abstract class BaseActivity : AppCompatActivity(), HasSupportFragmentInjector { @Inject @JvmField var navigationManager: NavigationManager? = null @Inject @JvmField var locationManager: MyLocationManagerImpl? = null @Inject @JvmField @Named(BaseActivityModule.ACTIVITY_FRAGMENT_MANAGER) //Tried to replace with option below //@field:Named(BaseActivityModule.ACTIVITY_FRAGMENT_MANAGER) var fragmentManager: FragmentManager? = null @Inject @JvmField var fragmentInjector: DispatchingAndroidInjector? = null override fun onCreate(@Nullable savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) } override fun supportFragmentInjector(): AndroidInjector? { return fragmentInjector } } 

BaseFragment

 abstract class BaseFragment : Fragment(), HasSupportFragmentInjector { @Inject @JvmField var activityContext: Context? = null @Inject @JvmField var parentActivity: FragmentActivity? = null @Inject @JvmField var fragmentListener: FragmentListener? = null @Inject @JvmField @Named(BaseFragmentModule.CHILD_FRAGMENT_MANAGER) //Also tried option below //@field:Named(BaseFragmentModule.CHILD_FRAGMENT_MANAGER) var ownChildFragmentManager: FragmentManager? = null @Inject @JvmField var childFragmentInjector: DispatchingAndroidInjector? = null override fun onAttach(context: Context) { AndroidSupportInjection.inject(this) if (context is FragmentListener) { parentActivity = context as FragmentActivity fragmentListener = context } super.onAttach(context) } @Suppress("DEPRECATION") override fun onAttach(activity: Activity) { AndroidSupportInjection.inject(this) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if(activity is FragmentListener) { parentActivity = activity as FragmentActivity fragmentListener = activity } } super.onAttach(activity) } override fun supportFragmentInjector(): AndroidInjector? { return childFragmentInjector } fun addChildFragment(@IdRes containerViewId: Int, fragment: Fragment) { childFragmentManager!!.beginTransaction() .add(containerViewId, fragment) .commit() } } 

此外,完整的错误代码被添加到顶部。

请尝试@Inject @field:Named在使用命名注释的每种情况下,请改为@Inject @Named 。 这帮了我。

好吧,在这种情况下,原因是在活动中的Fragment对象的非正确赋值,并将它们作为自己的属性来操作 – 更具体地说,在MainActivity内部,它通过主题types的域注入来扩展基类。

所以是的,匕首错误日志给了间接暗示在哪里挖。