有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java我无法提供ViewModel

当我在@ContributesAndroidInjector(modules = [MainFragmentBuilderModule::class, LoginViewModelProviderModule::class])中包含LoginViewModelProviderModule时,我无法使用LoginViewModelProviderModule提供LoginViewModel,但当我在ActivityBuilderModule类的@Module annotation中包含它时,它可以工作

基本应用程序组件

@Suppress("unused")
@Singleton
@Component(
    modules = [AndroidInjectionModule::class,
        ActivityBuilderModule::class,
        ViewModelFactoryModule::class]
)
interface BaseApplicationComponent : AndroidInjector<BaseApplicationClass> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): BaseApplicationComponent
    }
}

活动构建模块

@Module
abstract class ActivityBuilderModule {

    @LoginScope
    @ContributesAndroidInjector(modules = [MainFragmentBuilderModule::class, LoginViewModelProviderModule::class])
    abstract fun contributeMainActivity(): MainActivity
}

MainFragmentBuilderModule

@Module
abstract class MainFragmentBuilderModule {

    @ContributesAndroidInjector
    abstract fun contributesLoginFragment(): LoginFragment
}

LoginViewModelProviderModule

@Suppress("unused")
@Module
abstract class LoginViewModelProviderModule {
    @Binds
    @IntoMap
    @ViewModelKey(LoginViewModel::class)
    abstract fun bindLoginViewModel(viewModel: LoginViewModel): ViewModel
}

ViewModelFactoryModule

@Module
abstract class ViewModelFactoryModule {

    @Binds
    abstract fun bindViewModelFactory(viewModelProviderFactory: ViewModelProviderFactory): ViewModelProvider.Factory
}

ViewModelProviderFactory

@Singleton
class ViewModelProviderFactory @Inject constructor(
    private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val creator = creators[modelClass] ?: creators.entries.firstOrNull {
            modelClass.isAssignableFrom(it.key)
        }?.value ?: throw IllegalArgumentException("unknown model class $modelClass") as Throwable
        try {
            @Suppress("UNCHECKED_CAST")
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }
}

登录范围

@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class LoginScope 

ViewModelKey

@MustBeDocumented
@Target(
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)

这就是我看到的错误:

错误:[Dagger/MissingBinding]java。util。地图,javax。注射供应商>;如果没有@Providers注释的方法,则无法提供。 基于公共抽象接口的应用程序组件扩展了dagger。安卓雄激素注射器{ ^ JAVAutil。地图,javax。注射供应商>;注射于 通用域名格式。实例MyDemo应用程序。viewmodel_工厂。ViewModelProviderFactory(创建者) 通用域名格式。实例MyDemo应用程序。viewmodel_工厂。ViewModelProviderFactory是在 通用域名格式。实例MyDemo应用程序。登录片段。viewModelProviderFactory 通用域名格式。实例MyDemo应用程序。LoginFragment是在 匕首安卓雄激素注射器。注入(T)[com.example.mydemoapplication.dagger.BaseApplicationComponent?com.example.mydemoapplication.dagger.ActivityBuilderModule_ContributeMainActivity.MainActivitySubcomponent?com.example.mydemoapplication.dagger.MainFragmentBuilderModule_contributeSLoginFragmentSubComponent]


共 (1) 个答案

  1. # 1 楼答案

    您只能在应用程序中创建绑定所有viewmodel的模块。你可以在我的示例应用程序中看到详细信息: sample-moviedb-app

    基本应用组件:

    @Suppress("unused")
    @Singleton
    @Component(
        modules = [AndroidInjectionModule::class,
            ActivityBuilderModule::class,
            ViewModelFactoryModule::class,
            ViewModelModule::class]
    
    )
    interface BaseApplicationComponent : AndroidInjector<BaseApplicationClass> {
        @Component.Builder
        interface Builder {
    
            @BindsInstance
            fun application(application: Application): Builder
    
            fun build(): BaseApplicationComponent
        }
    }
    

    ViewModelModule:

    @Suppress("unused")
    @Module
    abstract class ViewModelProviderModule {
        @Binds
        @IntoMap
        @ViewModelKey(LoginViewModel::class)
        abstract fun bindLoginViewModel(viewModel: LoginViewModel): ViewModel
    
    //other viewmodels in application
       @Binds
       abstract fun bindViewModelFactory(viewModelProviderFactory:ViewModelProviderFactory): ViewModelProvider.Factory
    }
    

    main模块:

    @Module
    class MainModule {
        @MainActivityScope
        @Provides
        fun provideViewModel(mainActivity: MainActivity, viewModelFactory: ViewModelProviderFactory) =
            ViewModelProviders.of(mainActivity, viewModelFactory).get(LoginViewModel::class.java)
    }
    

    LoginView模型:

    class LoginViewModel @Inject constructor(
    ) : ViewModel() {
    
    }