提问者:小点点

HILT:尚未在ViewModel中初始化lateinit属性存储库


我在带有 HILT 的多模块Android项目中面临这个问题。

 kotlin.UninitializedPropertyAccessException: lateinit property repository has not been initialized in MyViewModel

我的模块是

  1. 应用程序模块
  2. Viewmodel模块
  3. 用例模块
  4. 数据源模块

'应用模块'

@AndroidEntryPoint
class MainFragment : Fragment() {
private lateinit var viewModel: MainViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View {
    return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
    viewModel.test()
}}

'视图模型模块'

class MainViewModel @ViewModelInject constructor(private val repository: MyUsecase): ViewModel() {
fun test(){
    repository.test()
}}

'用例模块'

class MyUsecase @Inject constructor() {

@Inject
lateinit var feature: Feature

fun doThing() {
    feature.doThing()
}

@Module
@InstallIn(ApplicationComponent::class)
object FeatureModule {
    @Provides
    fun feature(realFeature: RealFeature): Feature = realFeature
}
}

数据源模块

interface Feature {
fun doThing()
}

class RealFeature : Feature {
override fun doThing() {
    Log.v("Feature", "Doing the thing!")
}
}

依赖性是

我的碎片-

我对这段代码做错了什么,请纠正它。


共3个答案

匿名用户

您必须在activity类上方添加注释@ AndroidEntryPoint,如下所示:

@androidEntry Point类主要活动:AppCompat活动(){

匿名用户

代码中的问题是@ViewModelInject不像在其他类中那样@Inject工作。不能在视图模型中执行字段注入。

你应该做:

class MainViewModel @ViewModelInject constructor(
  private val myUseCase: MyUsecase
): ViewModel() {

  fun test(){
    myUseCase.test()
  }
}

考虑对< code>MyUsecase类采用相同的模式。依赖项应该在构造函数中传递,而不是在类体中< code>@Inject传递。这违背了依赖注入的目的。

匿名用户

除了将所有内容移动到构造函数注入之外,您的 RealFeature 不会被注入,因为您可以手动实例化它,而不是让 Dagger 为您构建它。请注意 FeatureModule 如何直接调用 RealFeature 的构造函数,并为 @Provides 方法返回它。Dagger 将按原样使用此对象,因为它认为您已经完成了所有设置。场注入只有在你让匕首构建它时才有效。

您的功能模块应该如下所示:

@Module
@InstallIn(ApplicationComponent::class)
object FeatureModule {
    @Provides
    fun feature(realFeature: RealFeature): Feature = realFeature
}

或者使用@Binds注释:

@Module
@InstallIn(ApplicationComponent::class)
interface FeatureModule {
    @Binds
    fun feature(realFeature: RealFeature): Feature
}

这也强调了为什么您应该转向构造函数注入;使用构造函数注入,这个错误是不可能的。