web-dev-qa-db-ja.com

短剣:@ViewModelinjectはMyViewModelとクラッシュを注入していませんか?

短剣のViewModelinjectを探索する際に、 https://developer.android.com/training/dependency-injection/hilt-jetpack#view内モーデル

次のように私の活動に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<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)

View Model Factory(非注入アプローチ)を使って手動でビューモデルを作成してみてください。

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の使用に問題がありましたか?

9
Elye

私にとって、すべての依存関係は完全に配置されていましたが、ViewModelクラスを継承する上で逃しました(Androidx.Lifecycle.ViewModel)

ViewModel()

class MainViewModel @ViewModelInject constructor(): ViewModel() 
 _
0
Manti_Core

マルチモジュールプロジェクトの場合は、kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'モジュールにも:appを持つ必要があります。

0
Jim