You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在ViewModel中使用Koin的inject()注入类实例时出现无法导入inject()的问题

在ViewModel中使用Koin的inject()注入类实例时出现无法导入inject()的问题

看起来你遇到的问题是ViewModel类本身不符合Koin普通inject()方法的接收者要求,我来给你拆解下原因和解决办法:

问题原因

你看到的错误提示里提到「接收者类型不匹配」,是因为当前能找到的inject()方法是给ComponentCallbacks(比如Activity、Fragment这类实现了该接口的Android组件)设计的,而你的LoginViewModel继承的BaseViewModel本质是androidx.lifecycle.ViewModel,它并没有实现ComponentCallbacks接口,所以直接调用by inject()就会报错。

解决办法

这里给你几个可行的方案,你可以根据自己的项目情况选择:

  • 方案一:让BaseViewModel实现KoinComponent接口
    这是最直接的修复方式,只要让你的BaseViewModel实现org.koin.core.KoinComponent接口,它的所有子类(包括你的LoginViewModel)就能正常使用by inject()语法了:

    import org.koin.core.KoinComponent
    import androidx.lifecycle.ViewModel
    
    class BaseViewModel<S, E>: ViewModel(), KoinComponent {
        // 你的BaseViewModel原有逻辑
    }
    

    改完之后,LoginViewModel里的private val authProvider: AuthProvider by inject()就能正常识别和导入了。

  • 方案二:用构造函数注入(Koin官方推荐)
    其实Koin官方更推荐在ViewModel中使用构造函数注入的方式,这种方式不仅代码更清晰,还不需要依赖Koin的特定接口:
    首先修改LoginViewModel,把依赖放到构造函数里:

    class LoginViewModel(
        private val authProvider: AuthProvider
    ): BaseViewModel<LoginViewModelContract.State, LoginViewModelContract.Event>() {
        // 你的LoginViewModel原有逻辑
    }
    

    然后在你的Koin模块声明里,用viewModel函数来关联这个ViewModel和它的依赖:

    module {
        viewModel { LoginViewModel(get()) }
        // 别忘了声明AuthProvider的注入,比如单例:
        single { AuthProvider() }
    }
    

    这样Koin会自动帮你把AuthProvider注入到LoginViewModel的构造函数里,完全不需要在ViewModel里写by inject()

  • 方案三:直接通过Koin实例获取依赖
    如果不想修改BaseViewModel的结构,也可以直接调用Koin的全局实例来获取依赖:

    // 懒加载方式
    private val authProvider: AuthProvider by lazy { getKoin().get() }
    // 或者用Lazy的inject方式
    private val authProvider: Lazy<AuthProvider> = getKoin().inject()
    

另外要确认下你已经添加了Koin AndroidX ViewModel的依赖(如果是新Koin版本的话,依赖是io.insert-koin:koin-androidx-viewmodel),不过既然你其他类能正常注入,这个依赖应该已经配置好了。

备注:内容来源于stack exchange,提问作者padmalcom

火山引擎 最新活动