Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java I';我无法提供ViewModel_Java_Android_Kotlin_Dagger 2 - Fatal编程技术网

Java I';我无法提供ViewModel

Java I';我无法提供ViewModel,java,android,kotlin,dagger-2,Java,Android,Kotlin,Dagger 2,当我在@ContributesAndroidInjector(modules=[MainFragmentBuilderModule::class,LoginViewModelProviderModule::class])中包含LoginViewModelProviderModule时,我无法使用LoginViewModel模块提供LoginViewModel。但当我在ActivityBuilderModule类的@Module注释中包含它时,它就可以工作 基本应用程序组件 @Suppress("

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

基本应用程序组件

@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
    }
}
MainFragmentBuilderModule

@Module
abstract class ActivityBuilderModule {

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

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

    @Binds
    abstract fun bindViewModelFactory(viewModelProviderFactory: ViewModelProviderFactory): ViewModelProvider.Factory
}
@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class LoginScope 
LoginViewModelProviderModule

@Module
abstract class ActivityBuilderModule {

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

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

    @Binds
    abstract fun bindViewModelFactory(viewModelProviderFactory: ViewModelProviderFactory): ViewModelProvider.Factory
}
@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class LoginScope 
ViewModelFactoryModule

@Module
abstract class ActivityBuilderModule {

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

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

    @Binds
    abstract fun bindViewModelFactory(viewModelProviderFactory: ViewModelProviderFactory): ViewModelProvider.Factory
}
@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class LoginScope 
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)
        }
    }
}
@MustBeDocumented
@Target(
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
ViewModelKey

@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)
        }
    }
}
@MustBeDocumented
@Target(
    AnnotationTarget.FUNCTION,
    AnnotationTarget.PROPERTY_GETTER,
    AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
@必须记录
@目标(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY\u GETTER,
AnnotationTarget.PROPERTY\u SETTER
)
@保留(AnnotationRetention.RUNTIME)
@地图键
注释类ViewModelKey(val值:KClass)
这就是我看到的错误:

@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
    }
}
@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
}
@Module
class MainModule {
    @MainActivityScope
    @Provides
    fun provideViewModel(mainActivity: MainActivity, viewModelFactory: ViewModelProviderFactory) =
        ViewModelProviders.of(mainActivity, viewModelFactory).get(LoginViewModel::class.java)
}
class LoginViewModel @Inject constructor(
) : ViewModel() {

}
错误:[Dagger/MissingBinding]java.util.Map,javax.inject.Provider>如果没有@Provides注释方法,则无法提供。 基于公共抽象接口的ApplicationComponent扩展了dagger.android.AndroidJector{ ^ java.util.Map、javax.inject.Provider>在 com.example.mydemoapplication.viewmodel\u factory.ViewModelProviderFactory(创建者) com.example.mydemoapplication.viewmodel_factory.ViewModelProviderFactory在 com.example.mydemoapplication.LoginFragment.viewModelProviderFactory com.example.mydemoapplication.LoginFragment在
dagger.android.Androidjector.inject(T)[com.example.mydemoapplication.dagger.BaseApplicationComponent?com.example.mydemoapplication.dagger.ActivityBuilderModule_ContributeMainActivity.MainActivitySubcomponent?com.example.mydemoapplication.dagger.MainFragmentBuilderModule_contributeSLoginFragmentSubComponent]

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

基本应用程序组件:

@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
    }
}
@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
}
@Module
class MainModule {
    @MainActivityScope
    @Provides
    fun provideViewModel(mainActivity: MainActivity, viewModelFactory: ViewModelProviderFactory) =
        ViewModelProviders.of(mainActivity, viewModelFactory).get(LoginViewModel::class.java)
}
class LoginViewModel @Inject constructor(
) : ViewModel() {

}
main模块:

@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
    }
}
@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
}
@Module
class MainModule {
    @MainActivityScope
    @Provides
    fun provideViewModel(mainActivity: MainActivity, viewModelFactory: ViewModelProviderFactory) =
        ViewModelProviders.of(mainActivity, viewModelFactory).get(LoginViewModel::class.java)
}
class LoginViewModel @Inject constructor(
) : ViewModel() {

}
登录视图模型:

@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
    }
}
@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
}
@Module
class MainModule {
    @MainActivityScope
    @Provides
    fun provideViewModel(mainActivity: MainActivity, viewModelFactory: ViewModelProviderFactory) =
        ViewModelProviders.of(mainActivity, viewModelFactory).get(LoginViewModel::class.java)
}
class LoginViewModel @Inject constructor(
) : ViewModel() {

}

更新-
ViewModelProviderFactory
不应为单例,删除此选项可修复此问题