如果没有@Provides-annotated方法,就不能提供MainActivityModule。

问题描述 投票:0回答:1

我第一次在android中使用dagger2,并尝试使用与dagger2相同的结构来反映我的项目。google/iosched. 但当我编译下面这个简单的项目时,它却报告了以下内容 MainActivityModule 不能在其中使用。

// MainApplication.kt

class MainApplication : DaggerApplication() {

    ...

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.factory().create(this)
    }

    ...
}


// AppComponent.kt

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        AppModule::class,
        ActivityBindingModule::class,
        ViewModelModule::class
    ]
)
interface AppComponent : AndroidInjector<MainApplication> {
    @Component.Factory
    interface Factory {
        fun create(@BindsInstance application: MainApplication): AppComponent
    }
}


// ActivityBindingModule.kt

@Module
@Suppress("UNUSED")
abstract class ActivityBindingModule {

    @ActivityScoped
    @ContributesAndroidInjector(
        modules = [
            // activity
            MainActivityModule::class
        ]
    )
    internal abstract fun mainActivity(): MainActivity
}


// MainActivity.kt

class MainActivity : DaggerAppCompatActivity() {

    @Inject lateinit var viewModelFactory: ViewModelProvider.Factory
    @Inject lateinit var viewModel: MainActivityModule

    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.AppTheme)
        super.onCreate(savedInstanceState)

        viewModel = viewModelProvider(viewModelFactory)
    }
    ...
}


// MainActivityModule.kt

@Module
@Suppress("UNUSED")
abstract class MainActivityModule {

    @Binds
    @IntoMap
    @ViewModelKey(MainActivityViewModel::class)
    internal abstract fun bindViewModel(viewModel: MainActivityViewModel): ViewModel
}


// MainActivityViewModel.kt

class MainActivityViewModel @Inject constructor(

) : ViewModel() {

}

下面的错误信息。

[Dagger/MissingBinding] com.example.app.di.MainActivityModule cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.app.MainApplication> {
                ^
      com.example.app.di.MainActivityModule is injected at
          com.example.app.ui.MainActivity.viewModel
      com.example.app.ui.MainActivity is injected at
android dagger-2
1个回答
1
投票

注意 iosched 示例 MainActivity.kt:116 注入一个MainActivity查看模型:

private lateinit var viewModel: MainActivityViewModel

当你注入了一个MainActivity的时候模块:

@Inject lateinit var viewModel: MainActivityModule

有几个说明。

  1. 模块是用来配置Dagger的 你永远不需要注入或参考 模块 从您的ViewModels、Activity、Views或其他类。在所有情况下,您应该只与模块实例进行交互 如果 你有一个不是接口或抽象(开放)类的Module,而且它没有一个公共的无参数构造函数。

  2. 尽管你几乎不应该在你的图中注入模块,但Dagger会在你的图中注入 允许 你这样做 如果且仅如果 它们在你的图中被绑定。你应该这样理解错误信息。"com.example.app.di.MainActivityModule不能在没有@Provides-annotated方法的情况下被提供";因为你已经通过 @Inject 而Dagger不知道如何提供一个,它就会抛出这个编译时异常。

  3. 请注意,iosched的MainActivity.kt并没有将MainActivityViewModel标记为可注入的,它是手动创建实例。在第136行 就像你在这里发布的代码一样。要么你应该构造实例,要么Dagger应该构造实例,但不能同时构造。(Dagger 偶尔会对填充 @Inject 字段,但在这里你不需要这样做)。) 所以在任何情况下,你都可以放弃 @Inject 注释,小刀就不再担心了。

© www.soinside.com 2019 - 2024. All rights reserved.