短剣の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
の使用に問題がありましたか?
私にとって、すべての依存関係は完全に配置されていましたが、ViewModelクラスを継承する上で逃しました(Androidx.Lifecycle.ViewModel)
ViewModel()
class MainViewModel @ViewModelInject constructor(): ViewModel()
_
マルチモジュールプロジェクトの場合は、kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
モジュールにも:app
を持つ必要があります。