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

Aru*_*run 5 android dagger-2 dagger-hilt

我在使用 HILT 的多模块 android 项目中面临这个问题。

 kotlin.UninitializedPropertyAccessException: lateinit property repository has not been initialized in MyViewModel
Run Code Online (Sandbox Code Playgroud)

我的模块是

  1. 应用模块
  2. 视图模型模块
  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()
}}
Run Code Online (Sandbox Code Playgroud)

'视图模型模块'

class MainViewModel @ViewModelInject constructor(private val repository: MyUsecase): ViewModel() {
fun test(){
    repository.test()
}}
Run Code Online (Sandbox Code Playgroud)

'用例模块'

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
}
}
Run Code Online (Sandbox Code Playgroud)

'数据源模块'

interface Feature {
fun doThing()
}

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

依赖是

MyFragment ---> MyViewModel ---> MyUseCase ---> 数据源

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

小智 15

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

@AndroidEntryPoint 类 MainActivity : AppCompatActivity() {


小智 1

代码中的问题是它@ViewModelInject不像@Inject其他类那样工作。您无法在 ViewModel 中执行字段注入。

你应该做:

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

  fun test(){
    myUseCase.test()
  }
}
Run Code Online (Sandbox Code Playgroud)

考虑在班级中遵循相同的模式MyUsecase。依赖关系应该在构造函数中传递,而不是@Inject在类主体中传递。这违背了依赖注入的目的。