首页 > 解决方案 > 使用 Hilt 的动态模块上的 InstantiationException

问题描述

试图通过阅读文档来解决这个问题,并且我也遵循了这个例子。但我没有成功。所以我需要找出我错过了什么或做错了什么。

我有一个应用程序模块,其@HiltAndroidApp位置:

@HiltAndroidApp
class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()
        ...
    }
}

现在我有一个 :core 模块,我的FirebaseAuth依赖项是从一个模块生成的:

@Module
@InstallIn(ApplicationComponent::class)
class FirebaseModule{
    @Provides
    fun provideFirebaseAuth() : FirebaseAuth = FirebaseAuth.getInstance()
}

还有一个:login模块,我被困在其中。在继续之前::app模块实现:core:login模块。

现在我创建了一个LoginModuleDependenciesin :core

@EntryPoint
@InstallIn(ApplicationComponent::class)
interface LoginModuleDependencies {
    fun firebaseAuth(): FirebaseAuth
}

所以我假设这个是为了暴露动态特性之间的依赖关系。跳转到LoginComponent(在 ':login' 模块中),我这样做:

@Component(dependencies = [LoginModuleDependencies::class])
interface LoginComponent {
    fun inject(loginFragment: LoginFragment)

    @Component.Factory
    interface Factory {
        fun create(
            loginModuleDependencies: LoginModuleDependencies
        ): LoginComponent
    }
}

根据文档,它允许我这样做:

@OptIn(ExperimentalCoroutinesApi::class)
class LoginFragment : Fragment(R.layout.fragment_login) {

    private val loginViewModel: LoginViewModel by viewModels()
    private var fragmentLoginBinding: FragmentLoginBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        DaggerLoginComponent.factory()
            .create(
                loginModuleDependencies = EntryPointAccessors.fromApplication(
                    requireActivity().applicationContext,
                    LoginModuleDependencies::class.java
                )
            ).inject(this)
        super.onCreate(savedInstanceState)
    }
...
}

崩溃:RuntimeException: Cannot create an instance of class com.coroutinedispatcher.login.LoginViewModel 进一步跟踪日志:

Caused by: java.lang.InstantiationException: java.lang.Class<com.coroutinedispatcher.login.LoginViewModel> has no zero argument constructor

这就是假设我要么错过了什么,要么做错了什么。

因为我的LoginViewModel样子是这样的:

class LoginViewModel @ViewModelInject constructor(private val firebaseAuth: FirebaseAuth, @Assisted private val savedStateHandle: SavedStateHandle) : ViewModel()

我可以验证如果我在相应的片段中进行字段注入,FirebaseAuth则检索到该实例。

那么,我目前做错了什么?

编辑:所以基本上,我能够确认我可以从中撤出,ApplicationComponent因为这样做:

@Inject lateinit var firebaseAuth: FirebaseAuth

// onViewCreated
Log.d(someClassName, "value: ${::firebaseAuth.isInitialized}") // true

而且,创建一个新的普通类来拉那个 dep ,工作:

class SomeWeirdClass @Inject constructor(private val firebaseAuth: FirebaseAuth)

在片段上记录

Log.d(someClassName, "value: ${::someWeirdClass.isInitialized}") // true

所以我认为可能存在版本控制问题,但我就是不知道是什么问题。提供一个ViewModelProvider.Factory作品,但如果你应该使用它,那么使用它有什么意义呢@ViewModelInject

标签: androidkotlindaggerdagger-hilt

解决方案


推荐阅读