依存関係を使用して ViewModel を作成する Android Jetpack の一部
依存関係注入のベスト プラクティスに基づいて、ViewModel は
コンストラクタのパラメータとして依存関係を取得できます。ほとんどの場合、これらはドメインレイヤまたはデータレイヤのタイプです。フレームワークは ViewModel を提供しているため、ViewModel のインスタンスを作成するには特別なメカニズムが必要です。そのメカニズムとは、ViewModelProvider.Factory インターフェースです。このインターフェースの実装のみが、適切なスコープで ViewModel をインスタンス化することができます 。
CreationExtras の ViewModel
ViewModel クラスがコンストラクタで依存関係を受け取る場合は、ファクトリが ViewModelProvider.Factory インターフェースを実装するようにします。create(Class<T>, CreationExtras) 関数をオーバーライドして、ViewModel の
新しいインスタンスを提供します。
CreationExtras を使用すると、ViewModel のインスタンス化に役立つ関連情報にアクセスできます。エクストラからアクセスできるキーのリストは次のとおりです。
| キー | 機能 |
|---|---|
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY |
ViewModelProvider.get() に渡したカスタムキーにアクセスできます。 |
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY |
Application クラスのインスタンスにアクセスできます。 |
SavedStateHandleSupport.DEFAULT_ARGS_KEY |
SavedStateHandle の作成に使用する引数のバンドルにアクセスできます。 |
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY |
ViewModel の作成に使用されている SavedStateRegistryOwner にアクセスできます。 |
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY |
ViewModelStoreOwner の作成に使用されている ViewModel にアクセスできます。 |
SavedStateHandle の新しいインスタンスを作成するには、
CreationExtras.createSavedStateHandle()
関数を使用して、ViewModel に渡します。
APPLICATION_KEY を使用した CreationExtras
次の例は、ViewModel が リポジトリ を Application クラスと SavedStateHandle を依存関係として取得する方法の例です。
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// ViewModel logic
// ...
// Define ViewModel factory in a companion object
companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
val savedStateHandle = createSavedStateHandle()
val myRepository = (this[APPLICATION_KEY] as MyApplication).myRepository
MyViewModel(
myRepository = myRepository,
savedStateHandle = savedStateHandle
)
}
}
}
}
次に、ViewModel のインスタンスを取得するときに、このファクトリを使用できます。
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
modifier: Modifier = Modifier,
viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
// ...
}
カスタム パラメータを CreationExtras として渡す
カスタムキーを作成することで、CreationExtras を介して ViewModel に依存関係を渡すことができます。
これは、ViewModel が Application クラスと APPLICATION_KEY を介してアクセスできないオブジェクトに依存している場合に便利です。たとえば、ViewModel が Kotlin Multiplatform モジュール内で作成されているため、Android の依存関係にアクセスできない場合などです。
この例では、ViewModel はカスタムキーを定義し、
ViewModelProvider.Factory で使用しています。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
) : ViewModel() {
// ViewModel logic
// Define ViewModel factory in a companion object
companion object {
// Define a custom key using the factory function
val MY_REPOSITORY_KEY = CreationExtras.Key<MyRepository>()
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
// Get the dependency in your factory
val myRepository = this[MY_REPOSITORY_KEY] as MyRepository
MyViewModel(
myRepository = myRepository,
)
}
}
}
}
CreationExtras.Key を使用して、コンポーザブルで ViewModel を直接インスタンス化できます。
import androidx.lifecycle.viewmodel.MutableCreationExtras
import androidx.lifecycle.viewmodel.compose.viewModel
// ...
@Composable
fun MyApp(myRepository: MyRepository) {
val extras = MutableCreationExtras().apply {
set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
}
val viewModel: MyViewModel = viewModel(
factory = MyViewModel.Factory,
extras = extras,
)
}
参考情報
ViewModel と依存関係について詳しくは、次の参考情報をご覧ください。
ドキュメント
Views のコンテンツ
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- ViewModel の保存済み状態のモジュール
- UI の状態を保存する