ViewModels mit Abhängigkeiten erstellen   Teil von Android Jetpack.

Gemäß den Best Practices für die Abhängigkeitsinjektion können ViewModels Abhängigkeiten als Parameter in ihrem Konstruktor annehmen. Dabei handelt es sich meist um Typen aus den Domain- oder Datenschichten. Da das Framework die ViewModels bereitstellt, ist ein spezieller Mechanismus erforderlich, um Instanzen davon zu erstellen. Dieser Mechanismus ist die Schnittstelle ViewModelProvider.Factory. Nur Implementierungen dieser Schnittstelle können ViewModels im richtigen Bereich instanziieren.

ViewModels mit CreationExtras

Wenn eine ViewModel Klasse Abhängigkeiten in ihrem Konstruktor empfängt, stellen Sie eine Factory bereit, die die ViewModelProvider.Factory Schnittstelle implementiert. Überschreiben Sie die create(Class<T>, CreationExtras) Funktion, um eine neue Instanz des ViewModel bereitzustellen.

CreationExtras ermöglicht den Zugriff auf relevante Informationen, die bei der Instanziierung eines ViewModel helfen. Hier ist eine Liste der Schlüssel, auf die über Extras zugegriffen werden kann:

Schlüssel Funktionen
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY Ermöglicht den Zugriff auf den benutzerdefinierten Schlüssel, den Sie an ViewModelProvider.get() übergeben haben.
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY Ermöglicht den Zugriff auf die Instanz der Klasse Application.
SavedStateHandleSupport.DEFAULT_ARGS_KEY Ermöglicht den Zugriff auf das Bundle von Argumenten, das Sie zum Erstellen von SavedStateHandle verwenden sollten.
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY Ermöglicht den Zugriff auf den SavedStateRegistryOwner, der zum Erstellen des ViewModel verwendet wird.
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY Ermöglicht den Zugriff auf den ViewModelStoreOwner, der zum Erstellen des ViewModel verwendet wird.

Verwenden Sie die CreationExtras.createSavedStateHandle() Funktion, um eine neue Instanz von SavedStateHandle zu erstellen und sie an das ViewModel zu übergeben.

CreationExtras mit APPLICATION_KEY

Im Folgenden finden Sie ein Beispiel dafür, wie Sie eine Instanz eines ViewModel bereitstellen, das ein Repository mit dem Bereich der Klasse Application und SavedStateHandle als Abhängigkeiten verwendet:

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

Anschließend können Sie diese Factory verwenden, wenn Sie eine Instanz des ViewModel abrufen:

import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun MyScreen(
    modifier: Modifier = Modifier,
    viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
    // ...
}

Benutzerdefinierte Parameter als CreationExtras übergeben

Sie können Abhängigkeiten über CreationExtras an Ihr ViewModel übergeben, indem Sie einen benutzerdefinierten Schlüssel erstellen. Das kann nützlich sein, wenn Ihr ViewModel von Objekten abhängt, auf die nicht über die Klasse Application und APPLICATION_KEY zugegriffen werden kann. Ein Beispiel dafür ist, wenn Ihr ViewModel in einem Kotlin Multiplatform-Modul erstellt wird und daher keinen Zugriff auf Android-Abhängigkeiten hat.

In diesem Beispiel definiert das ViewModel einen benutzerdefinierten Schlüssel und verwendet ihn in der 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,
                )
            }
        }
    }
}

Sie können ein ViewModel mit einem CreationExtras.Key direkt in Ihren Composables instanziieren.

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,
    )
}

Zusätzliche Ressourcen

Weitere Informationen zu ViewModels und Abhängigkeiten finden Sie in den folgenden zusätzlichen Ressourcen:

Dokumentation

Inhalte ansehen