首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dagger-Hilt:@ViewModelInject没有注入MyViewModel并崩溃吗?

Dagger-Hilt:@ViewModelInject没有注入MyViewModel并崩溃吗?
EN

Stack Overflow用户
提问于 2020-06-30 21:55:25
回答 5查看 11.8K关注 0票数 13

在探索Dagger-Hilt的ViewModelInject时,我遵循了https://developer.android.com/training/dependency-injection/hilt-jetpack#viewmodels我尝试将ViewModel注入到我的活动中,如下所示

代码语言:javascript
复制
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 { 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("DefaultKey")

    val showTextDataNotifier: LiveData
        get() = showTextLiveData

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


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

It崩溃抱怨

代码语言:javascript
复制
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,它工作得很好。

代码语言:javascript
复制
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 { 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  create(key: String, modelClass: Class, 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("DefaultKey")

    val showTextDataNotifier: LiveData
        get() = showTextLiveData

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

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

我在使用的时候做错了什么吗?@ViewModelInject

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-06-30 22:13:46

显然,我错过了添加一个kapt,这是kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'中的依赖项列表build.gradle如下所示

代码语言:javascript
复制
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'

为了完整起见,下面是插件

代码语言:javascript
复制
apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'kotlin-kapt'
票数 31
EN

Stack Overflow用户

发布于 2021-02-25 17:20:47

@ViewModelInject在较新的版本中已被弃用。hilt版本https://developer.android.com/reference/androidx/hilt/lifecycle/ViewModelInject

使用HiltViewModel

代码语言:javascript
复制
@HiltViewModel
class TasksViewModel @Inject constructor(
    val taskRepository: TaskRepository
) : ViewModel() {

}
票数 25
EN

Stack Overflow用户

发布于 2021-01-04 01:59:25

尝试通过Find in Path (⇧⌘F或Ctrl+Shift+F)搜索ViewModel生成的java文件,如下所示。

如果没有自动生成的java文件。这意味着您忘记将此依赖项添加到模块的gradle文件中,该文件为@ViewModelInject注释。

kapt "androidx.hilt:hilt-compiler:$version"

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62659094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档