Dagger-Hilt: @ViewModelInject не внедряет MyViewModel и происходит сбой?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Dagger-Hilt: @ViewModelInject не внедряет MyViewModel и происходит сбой?

Сообщение Anonymous »

При изучении ViewModelInject Dagger-Hilt я следую примеру https://developer.android.com/training/ ... viewmodels
I попробуйте внедрить ViewModel в мою деятельность следующим образом:

Код: Выделить всё

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"
}

Жалуется на сбой

Код: Выделить всё

     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 вручную, используя фабрику модели представления (подход без внедрения), все работает нормально.

Код: Выделить всё

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?

Подробнее здесь: https://stackoverflow.com/questions/626 ... -and-crash
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»