【问题标题】:How to fix "[Dagger/MissingBinding] : Cannot be provided without an @Provides-annotated method"如何修复“[Dagger/MissingBinding]:没有@Provides-annotated 方法就无法提供”
【发布时间】:2019-11-04 04:51:59
【问题描述】:

我正在将匕首与viewmodel 集成。当我在AppComponent 中包含viewmodelprovider 工厂时,应用程序没有得到构建,并且它显示类似

的错误

“错误:[Dagger/MissingBinding] java.util.Map,javax.inject.Provider> 不能在没有@Provides-annotated 方法的情况下提供”。我在下面添加了我的代码。

ViewModelFactory

class DaggerViewModelFactory
@Inject
constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        var creator: Provider<out ViewModel>? = creators[modelClass]
        if (creator == null) {
            for ((key, value) in creators) {
                if (modelClass.isAssignableFrom(key)) {
                    creator = value
                    break
                }
            }
        }
        if (creator == null) {
            throw IllegalArgumentException("unknown model class " + modelClass)
        }
        try {
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    }
}

然后我有我的 AppComponent

@Singleton
@Component(modules = [AndroidInjectionModule::class, ViewModelFactoryModule::class, ActivityBuilder::class])
interface AppComponent : AndroidInjector<FreedomApplication> {

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: DaggerApplication): Builder

        fun build(): AppComponent

    }
}

我的viewmodel模块绑定类

@Module
abstract class WelcomeModule {
    @Binds
    @IntoMap
    @ViewModelKey(WelcomeViewModel::class)
    abstract fun bindWelcomeViewModel(welcomeViewModel: WelcomeViewModel): ViewModel
}

我的片段生成器类

@Module
abstract class FragmentBuilder {

    @ContributesAndroidInjector
    abstract fun injectWelcomeFragment() : WelcomeFragment

}

然后我的片段类包含 viewmodelprovider 工厂

class WelcomeFragment @Inject constructor(): DaggerFragment() {
    @Inject
    lateinit var providerFactory: ViewModelProvider.Factory

    companion object {
        fun newInstance() = WelcomeFragment()
    }

    private lateinit var viewModel: WelcomeViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.welcome_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this, providerFactory).get(WelcomeViewModel::class.java)
        // TODO: Use the ViewModel
    }
}

和视图模型为片段集成

class WelcomeViewModel @Inject constructor() : ViewModel() {

    // TODO: Implement the ViewModel
}

【问题讨论】:

  • 您可以查看 [How do I fix Dagger 2 error '... cannot be provided [...]'?](stackoverflow.com/q/44912080/1837367) 了解一些一般信息。如果您需要进一步的帮助,还请更新您的问题以包含 full 错误消息(如链接问题所示)。一眼看去,我看不到你在任何地方添加WelcomeModule
  • 我已经包含了我的欢迎模块。
  • 但你并没有在任何地方使用它 (@Component(modules = [ can't find it here or similar ]))
  • 你的错误解决了吗?
  • 是的@MohammedRampurawala

标签: android kotlin dagger-2


【解决方案1】:

已修复上述问题,请参考以下代码。

@Singleton
@Component(modules = [ActivityBuilder::class, NetworkModule::class, ViewBindModule::class, AndroidSupportInjectionModule::class])
interface AppComponent : AndroidInjector<FreedomApplication> {

    override fun inject(application: FreedomApplication)

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: FreedomApplication): Builder

        fun build(): AppComponent
    }

}
@Module
abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = [FragmentBuilder::class])
    abstract fun bindWelcomeActivity (): WelcomeActivity

    @ContributesAndroidInjector(modules = [FragmentBuilder::class])
    abstract fun bindDashBoardActivity (): DashBoardActivity
}
@Module
abstract class ViewBindModule {
    @Binds
    abstract fun bindViewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory

    @Binds
    @IntoMap
    @ViewModelKey(WelcomeViewModel::class)
    abstract fun bindWelcomeViewModel(viewModel: WelcomeViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(LoginViewModel::class)
    abstract fun bindLoginViewModel(viewModel: LoginViewModel): ViewModel

    @Binds
    @IntoMap
    @ViewModelKey(DashBoardViewModel::class)
    abstract fun bindDashboardViewModel(viewModel: DashBoardViewModel): ViewModel
}
class DaggerViewModelFactory @Inject constructor(private val creators: Map<Class <out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>):ViewModelProvider.Factory {

    @Suppress("UNCHECKED_CAST")

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
         var creator :Provider<ViewModel>? = creators[modelClass]

        if (creator == null)
            for ((key, value) in creators){
                if (modelClass.isAssignableFrom(key)){
                    creator = value
                    break
                }
            }

        if (creator == null) throw IllegalArgumentException("Unknown model class")
        try{
            return creator.get() as T
        }catch (e:Exception){
            throw RuntimeException(e)
        }
    }
}
abstract class FragmentBuilder {

    @ContributesAndroidInjector
    abstract fun bindWelcomeFragment(): WelcomeFragment

    @ContributesAndroidInjector
    abstract fun bindLoginFragment(): LoginFragment

    @ContributesAndroidInjector
    abstract fun bindDashBoardFragment(): DashBoardFragment
}

【讨论】:

    猜你喜欢
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多