添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

不能通过HiltViewModel的构造函数传递字符串 - 错误。[Dagger/MissingBinding] 不能提供java.lang.String。

2 人关注

我正在从Dagger 2迁移到Android的Hilt。 我的大部分迁移工作都是非常直接的,但是我正在转换的最后一个视图模型给我带来了麻烦

ContactDetailViewModel

@HiltViewModel
class ContactDetailViewModel
@Inject
constructor(
    application: Application,
    contactId: String?,
    name: String?,
    refId: String,
) : NetworkBaseViewModel(application) {
    .... (non-DI related code)
    @Inject
    lateinit var client: ApolloClient
    .... (non-DI related code and references to constructor params)

ContactDetailVMFactory

@Singleton
class ContactDetailVMFactory @Inject constructor(
    val application: Application,
    val contactId: String?,
    val name: String?,
    val refId: String
) : ViewModelProvider.AndroidViewModelFactory(application) {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return ContactDetailViewModel(application, contactId, name, refId) as T

ContactDetailEditFragment

@AndroidEntryPoint
open class ContactDetailEditFragment: Fragment() {
    val args: ContactDetailEditFragmentArgs by navArgs()
    open val vm by activityViewModels<ContactDetailViewModel>(
        factoryProducer = {
            ContactDetailVMFactory(
                    application = requireActivity().application,
                    contactId = args.contactId,
                    name = args.name,
                    refId = args.contactId ?: args.vmKey
        key = { args.vmKey }
    @Inject
    lateinit var client: ApolloClient

Errors / Build Output

/BaseApplication_HiltComponents.java:141: error: [Dagger/MissingBinding] java.lang.String cannot be provided
without an @Inject constructor or an @Provides-annotated method.
public abstract static class SingletonC implements BaseApplication_GeneratedInjector,
    java.lang.String is injected at
        com.companyname.contacts.vm.ContactDetailViewModel(…, name, …)
    com.companyname.contacts.vm.ContactDetailViewModel is injected at
        com.companyname.contacts.vm.ContactDetailViewModel_HiltModules.BindsModule.binds(vm)
    @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject
.Provider<androidx.lifecycle.ViewModel>> is requested at
    dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint
.getHiltViewModelMap() [com.companyname.BaseApplication_HiltComponents.SingletonC → com.companyname
.BaseApplication_HiltComponents.ActivityRetainedC → com.companyname.BaseApplication_HiltComponents
.ViewModelC]
It is also requested at:
    com.companyname.contacts.vm.ContactDetailViewModel(…, contactId, …)
    com.companyname.contacts.vm.ContactDetailViewModel(…, refId)

我对这个问题感到很困惑。 我已经研究了好几天了。 我有其他字符串被传递到其他HiltViewModels中,似乎没有问题。 我想知道这是否是ViewModelFactory的问题。

4 个评论
顺便说一句,当我需要将标识符传入Hilt视图模型的构造函数时,我使用了 @AssistedInject dagger.dev/dev-guide/assisted-injection.html .
如果你手动创建viewModel对象,我不确定拥有 @Inject constructor 是否有任何意义 ContactDetailViewModel(application, contactId, name, refId) as T
另外,DI如何确定哪个 String 参数是哪个( val name: String? val refId: String ),你没有使用限定词。 medium.com/mindorks/…
你还手动创建了 ContactDetailVMFactory 对象,所以它拥有 @Inject constructor (或被标记为 @Singleton )也是毫无意义的。
android
kotlin
migration
android-viewmodel
dagger-hilt
petestmart
petestmart
发布于 2022-07-26
1 个回答
xinaiz
xinaiz
发布于 2022-07-26
已采纳
0 人赞同

在所提供的代码内有很多问题(查看我的评论),但我要把它简化如下。

@HiltViewModel
class ContactDetailViewModel @Inject constructor(
    @ApplicationContext val application: Context, // cast to Application later
    val client: ApolloClient
    savedStateHandle: SavedStateHandle
) : NetworkBaseViewModel(application) { 
    // get fragment arguments via SavedStateHandle
    private val args = ContactDetailEditFragmentArgs.fromSavedStateHandle(savedStateHandle)