我正在尝试在我的 Android 项目中使用 Dagger 2。首先,我想利用两个组件分别负责注入(inject)应用程序范围和 Activity 范围的依赖项。作为基本引用,除其他外,我使用了 this answer

因此有两种不同的方式设置组件之间的关系:使用 @Subcomponent 注释和使用 dependencies 参数。

  • 如果我选择第一个,我的 AppContextComponent 工作正常。但是,一旦我尝试从 ActivityContextComponent 注入(inject)依赖项,就会收到此构建时错误:


  • 使用第二种方法,所有依赖项都会出现此错误。

  • 知道我 有提供方法,这个错误信息坦率地说是没有用的。这是我设法用谷歌搜索出来的这个错误的其他几个可能来源,但似乎并非如此:
  • Scoping problems
  • Ambuiguity due to the same return type from different provision methods (即使我删除了提供 Context 的方法,问题仍然存在)。

  • 以下代码在 Kotlin 中,但我认为它应该非常简单。

    应用程序组件
    object AppContext {
        // a singleton used in place of a Java static field
        @JvmStatic lateinit var graph: AppContextComponent
    }
    
    @ApplicationScope @Component(modules = arrayOf(AppContextModule::class))
    interface AppContextComponent {
        fun inject(fragment: BaseFragment)
    
        fun newActivityContextComponent(module: ActivityContextModule): ActivityContextComponent
    }
    
    @Module
    class AppContextModule(val app: MyApplication) {
        @Provides @ApplicationScope @ForApplication
        fun provideContext(): Context {
            return app;
        }
    
        @Provides @ApplicationScope
        fun provideMyApplicationContext(): MyApplication {
            return app;
        }
    }
    

    Activity 组件
    object ActivityContext {
        @JvmStatic lateinit var graph: ActivityContextComponent
    }
    
    @ActivityScope @Subcomponent(modules = arrayOf(ActivityContextModule::class))
    interface ActivityContextComponent {
        fun inject(fragment: BaseFragment)
    }
    
    @Module
    class ActivityContextModule(val activity: MainActivity) {
    
        // Worth pointing out is that the provision methods are not used.
        // That is, no code is being generated for them.
    
        @Provides @ActivityScope @ForActivity
        fun provideContext(): Context {
            return activity;
        }
    
        @Provides @ActivityScope
        fun provideMainActivityContext(): MainActivity {
            return activity;
        }
    }
    

    以下是这些组件的使用方式。

    应用程序
    class MyApplication : SugarApp() {
        override fun onCreate() {
            super.onCreate()
            AppContext.graph =
                DaggerAppContextComponent
                        .builder()
                        .appContextModule(AppContextModule(this))
                        .build()
        }
    }
    

    Activity
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            ActivityContext.graph =
                AppContext.graph
                     .newActivityContextComponent(ActivityContextModule(this))
        }
    }
    

    BaseFragment (实际注入(inject)发生的地方)
    abstract class BaseFragment : Fragment() {
        // works fine
        @Inject @ForApplication lateinit var myApplication: MyApplication
    
        // fails with "cannot be provided" error
        @Inject @ForActivity lateinit var myActivity: MainActivity
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            ActivityContext.graph.inject(this)
        }
    }
    

    我错过了什么?

    谢谢!

    最佳答案

    编辑

    要点是:

    如果您使用 dagger 的 @Subcomponent s,请确保父 @Component 中没有注入(inject)与子组件相同的目标类的方法。

    Dagger 会感到困惑,并会尝试生成代码以直接从父组件注入(inject)目标,但它没有满足注入(inject)依赖项所需的模块。

    关于android - Dagger 2 错误 : dependency “cannot be provided without an @Inject constructor” ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37225960/

    10-09 06:26
    查看更多