Dagger-Hilt:@ViewModelInject 没有注入 MyViewModel 并崩溃? [英] Dagger-Hilt: @ViewModelInject is not injecting MyViewModel and crash?

查看:35
本文介绍了Dagger-Hilt:@ViewModelInject 没有注入 MyViewModel 并崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在探索 Dagger-Hilt 的 ViewModelInject 时,我遵循了 中的示例https://developer.android.com/training/dependency-injection/hilt-jetpack#viewmodels

In exploring the ViewModelInject of Dagger-Hilt, I follow the example in https://developer.android.com/training/dependency-injection/hilt-jetpack#viewmodels

我尝试将 ViewModel 注入到我的活动中,如下

I try to inject the ViewModel into my activity as follow

import android.app.Application
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.hilt.Assisted
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.*
import androidx.savedstate.SavedStateRegistryOwner
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.HiltAndroidApp
import kotlinx.android.synthetic.main.activity_main.*
import javax.inject.Inject
import javax.inject.Singleton

@HiltAndroidApp
class MainApplication: Application()

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels()

    private val textDataObserver =
        Observer<String> { data -> text_view.text = data }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewModel.showTextDataNotifier.observe(this, textDataObserver)
        btn_fetch.setOnClickListener { viewModel.fetchValue() }
    }
}

class MyViewModel @ViewModelInject constructor(
    @Assisted val savedStateHandle: SavedStateHandle,
    val repository: Repository
) :
    ViewModel(), LifecycleObserver {

    private val showTextLiveData
            = savedStateHandle.getLiveData<String>("DefaultKey")

    val showTextDataNotifier: LiveData<String>
        get() = showTextLiveData

    fun fetchValue() {
        showTextLiveData.value = repository.getMessage()
    }
}


@Singleton
class Repository @Inject constructor() {
    fun getMessage() = "From Repository"
}

它崩溃抱怨

     Caused by: java.lang.RuntimeException: Cannot create an instance of class com.elyeproj.simplehilt.MyViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
        at androidx.hilt.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:69)

我尝试使用视图模型工厂(非注入方法)手动创建 ViewModel,效果很好.

I try manually creating the ViewModel using the view model factory (the non-injection approach), it works fine.

import android.app.Application
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.hilt.Assisted
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.*
import androidx.savedstate.SavedStateRegistryOwner
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.HiltAndroidApp
import kotlinx.android.synthetic.main.activity_main.*
import javax.inject.Inject
import javax.inject.Singleton

@HiltAndroidApp
class MainApplication: Application()

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels{
        MyViewModelFactory(this, Repository(), intent.extras)
    }

    private val textDataObserver =
        Observer<String> { data -> text_view.text = data }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewModel.showTextDataNotifier.observe(this, textDataObserver)
        btn_fetch.setOnClickListener { viewModel.fetchValue() }
    }
}

class MyViewModelFactory(
    owner: SavedStateRegistryOwner,
    private val repository: Repository,
    defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
    override fun <T : ViewModel> create(key: String, modelClass: Class<T>, handle: SavedStateHandle
    ): T {
        return MyViewModel(
            handle,
            repository
        ) as T
    }
}

class MyViewModel @ViewModelInject constructor(
    @Assisted val savedStateHandle: SavedStateHandle,
    val repository: Repository
) :
    ViewModel(), LifecycleObserver {

    private val showTextLiveData
            = savedStateHandle.getLiveData<String>("DefaultKey")

    val showTextDataNotifier: LiveData<String>
        get() = showTextLiveData

    fun fetchValue() {
        showTextLiveData.value = repository.getMessage()
    }
}

@Singleton
class Repository @Inject constructor() {
    fun getMessage() = "From Repository"
}

我在使用@ViewModelInject时有没有做错什么?

Did I do anything wrong in the use of @ViewModelInject?

推荐答案

显然我错过了添加一个 kapt,它是 kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'

Apparently I miss out adding a kapt, which is kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'

我的build.gradle中的依赖列表如下

    implementation 'androidx.fragment:fragment-ktx:1.2.5'
    implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
    implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01"
    implementation 'com.google.dagger:hilt-android:2.28-alpha'
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
    kapt 'com.google.dagger:hilt-android-compiler:2.28-alpha'

为了完整性,插件在下面

Just for completeness, the plugin is below

apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'kotlin-kapt'

这篇关于Dagger-Hilt:@ViewModelInject 没有注入 MyViewModel 并崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆