Android KTX   Teil von Android Jetpack.

Android KTX ist eine Reihe von Kotlin-Erweiterungen, die in Android Jetpack und anderen Android-Bibliotheken enthalten sind. KTX-Erweiterungen bieten prägnanten, idiomatischen Kotlin-Code für Jetpack, die Android-Plattform und andere APIs. Dazu werden in diesen Erweiterungen mehrere Kotlin-Sprachfunktionen verwendet, darunter:

  • Erweiterungsfunktionen
  • Eigenschaften der Erweiterung
  • Lambdas
  • Benannte Parameter
  • Standardwerte für Parameter
  • Koroutinen

Wenn Sie beispielsweise mit SharedPreferences arbeiten, müssen Sie einen Editor erstellen, bevor Sie Änderungen an den Einstellungen vornehmen können. Außerdem müssen Sie diese Änderungen übernehmen oder committen, wenn Sie mit der Bearbeitung fertig sind, wie im folgenden Beispiel gezeigt:

sharedPreferences
        .edit()  // create an Editor
        .putBoolean("key", value)
        .apply() // write to disk asynchronously

Kotlin-Lambdas eignen sich perfekt für diesen Anwendungsfall. Sie ermöglichen einen prägnanteren Ansatz, indem Sie einen Codeblock übergeben, der nach dem Erstellen des Editors ausgeführt werden soll. Der Code wird ausgeführt und die SharedPreferences API wendet die Änderungen dann atomar an.

Hier sehen Sie ein Beispiel für eine der Android KTX Core-Funktionen, SharedPreferences.edit, die SharedPreferences eine Bearbeitungsfunktion hinzufügt. Diese Funktion verwendet als erstes Argument ein optionales boolean-Flag, das angibt, ob die Änderungen übernommen oder angewendet werden sollen. Außerdem wird eine Aktion empfangen, die im SharedPreferences-Editor in Form eines Lambda-Ausdrucks ausgeführt werden soll.

// SharedPreferences.edit extension function signature from Android KTX - Core
// inline fun SharedPreferences.edit(
//         commit: Boolean = false,
//         action: SharedPreferences.Editor.() -> Unit)

// Commit a new value asynchronously
sharedPreferences.edit { putBoolean("key", value) }

// Commit a new value synchronously
sharedPreferences.edit(commit = true) { putBoolean("key", value) }

Der Anrufer kann entscheiden, ob die Änderungen übernommen werden sollen. Das action-Lambda ist selbst eine anonyme Erweiterungsfunktion für SharedPreferences.Editor, die Unit zurückgibt, wie durch die Signatur angegeben. Deshalb können Sie innerhalb des Blocks direkt auf der SharedPreferences.Editor arbeiten.

Schließlich enthält die SharedPreferences.edit()-Signatur das Schlüsselwort inline. Dieses Schlüsselwort weist den Kotlin-Compiler an, den kompilierten Bytecode für die Funktion jedes Mal zu kopieren und einzufügen (oder inline), wenn die Funktion verwendet wird. So wird der Aufwand vermieden, für jedes action jedes Mal, wenn diese Funktion aufgerufen wird, eine neue Klasse zu instanziieren.

Dieses Muster, Code mithilfe von Lambdas zu übergeben, sinnvolle Standardwerte anzuwenden, die überschrieben werden können, und diese Verhaltensweisen vorhandenen APIs mithilfe von inline-Erweiterungsfunktionen hinzuzufügen, ist typisch für die Verbesserungen, die durch die Android KTX-Bibliothek bereitgestellt werden.

Android KTX in Ihrem Projekt verwenden

Wenn Sie Android KTX verwenden möchten, fügen Sie die folgende Abhängigkeit in die Datei build.gradle Ihres Projekts ein:

Groovy

repositories {
    google()
}

Kotlin

repositories {
    google()
}

AndroidX-Module

Android KTX ist in Module unterteilt, wobei jedes Modul ein oder mehrere Pakete enthält.

Sie müssen für jedes Modul-Artefakt eine Abhängigkeit in der build.gradle-Datei Ihrer App angeben. Denken Sie daran, die Versionsnummer an das Artefakt anzuhängen. Die aktuellen Versionsnummern finden Sie im entsprechenden Abschnitt für jedes Artefakt in diesem Thema.

Android KTX enthält ein einziges Kernmodul, das Kotlin-Erweiterungen für gängige Framework-APIs und mehrere domänenspezifische Erweiterungen bietet.

Mit Ausnahme des Kernmoduls ersetzen alle KTX-Modul-Artefakte die zugrunde liegende Java-Abhängigkeit in Ihrer build.gradle-Datei. Sie können beispielsweise eine androidx.fragment:fragment-Abhängigkeit durch androidx.fragment:fragment-ktx ersetzen. Diese Syntax erleichtert die Verwaltung der Versionsverwaltung und erfordert keine zusätzlichen Abhängigkeitsdeklarationen.

Core KTX

Das Core KTX-Modul bietet Erweiterungen für gängige Bibliotheken, die Teil des Android-Frameworks sind. Diese Bibliotheken haben keine Java-basierten Abhängigkeiten, die Sie build.gradle hinzufügen müssen.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "androidx.core:core-ktx:1.16.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-ktx:1.16.0")
}

Hier finden Sie eine Liste der Pakete, die im Core KTX-Modul enthalten sind:

Collection KTX

Die Sammlungserweiterungen enthalten Dienstprogrammfunktionen für die Arbeit mit den speichereffizienten Sammlungsbibliotheken von Android, darunter ArrayMap, LongSparseArray und LruCache.

Wenn Sie dieses Modul verwenden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:

Groovy

dependencies {
    implementation "androidx.collection:collection-ktx:1.3.0"
}

Kotlin

dependencies {
    implementation("androidx.collection:collection-ktx:1.3.0")
}

Bei Sammlungserweiterungen wird die Operatorüberladung von Kotlin genutzt, um Dinge wie das Verketten von Sammlungen zu vereinfachen, wie im folgenden Beispiel gezeigt:

// Combine 2 ArraySets into 1.
val combinedArraySet = arraySetOf(1, 2, 3) + arraySetOf(4, 5, 6)

// Combine with numbers to create a new sets.
val newArraySet = combinedArraySet + 7 + 8

Fragment KTX

Das Fragment KTX-Modul bietet eine Reihe von Erweiterungen zur Vereinfachung der Fragment-API.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Cool

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.8.8"
}

Kotlin

dependencies {
    implementation("androidx.fragment:fragment-ktx:1.8.8")
}

Mit dem Fragment KTX-Modul können Sie Fragmenttransaktionen mit Lambdas vereinfachen, z. B.:

fragmentManager().commit {
   addToBackStack("...")
   setCustomAnimations(
           R.anim.enter_anim,
           R.anim.exit_anim)
   add(fragment, "...")
}

Sie können auch in einer Zeile an ein ViewModel binden, indem Sie die Property-Delegaten viewModels und activityViewModels verwenden:

// Get a reference to the ViewModel scoped to this Fragment
val viewModel by viewModels<MyViewModel>()

// Get a reference to the ViewModel scoped to its Activity
val viewModel by activityViewModels<MyViewModel>()

Lifecycle KTX

Lifecycle KTX definiert ein LifecycleScope für jedes Lifecycle-Objekt. Alle in diesem Bereich gestarteten Coroutinen werden abgebrochen, wenn Lifecycle zerstört wird. Sie können über die Properties lifecycle.coroutineScope oder lifecycleOwner.lifecycleScope auf die CoroutineScope von Lifecycle zugreifen.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
}

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
}

Das folgende Beispiel zeigt, wie Sie mit lifecycleOwner.lifecycleScope vorab berechneten Text asynchron erstellen:

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            val params = TextViewCompat.getTextMetricsParams(textView)
            val precomputedText = withContext(Dispatchers.Default) {
                PrecomputedTextCompat.create(longTextContent, params)
            }
            TextViewCompat.setPrecomputedText(textView, precomputedText)
        }
    }
}

LiveData KTX

Wenn Sie LiveData verwenden, müssen Sie Werte möglicherweise asynchron berechnen. Sie möchten beispielsweise die Einstellungen eines Nutzers abrufen und in Ihrer Benutzeroberfläche anzeigen. Für diese Fälle bietet LiveData KTX eine liveData-Builder-Funktion, die eine suspend-Funktion aufruft und das Ergebnis als LiveData-Objekt bereitstellt.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
}

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
}

Im folgenden Beispiel ist loadUser() eine an anderer Stelle deklarierte Suspend-Funktion. Mit der Builder-Funktion liveData können Sie loadUser() asynchron aufrufen und dann mit emit() das Ergebnis ausgeben:

val user: LiveData<User> = liveData {
    val data = database.loadUser() // loadUser is a suspend function.
    emit(data)
}

Weitere Informationen zur Verwendung von Coroutinen mit LiveData finden Sie unter Kotlin-Coroutinen mit Architekturkomponenten verwenden.

Jede Komponente der Navigationsbibliothek hat eine eigene KTX-Version, die die API anpasst, um sie prägnanter und Kotlin-idiomatisch zu gestalten.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um diese Module einzubinden:

Groovy

dependencies {
    implementation "androidx.navigation:navigation-runtime-ktx:2.7.5"
    implementation "androidx.navigation:navigation-fragment-ktx:2.7.5"
    implementation "androidx.navigation:navigation-ui-ktx:2.7.5"
}

Kotlin

dependencies {
    implementation("androidx.navigation:navigation-runtime-ktx:2.7.5")
    implementation("androidx.navigation:navigation-fragment-ktx:2.7.5")
    implementation("androidx.navigation:navigation-ui-ktx:2.7.5")
}

Verwenden Sie die Erweiterungsfunktionen und die Delegierung von Eigenschaften, um auf Zielargumente zuzugreifen und zu Zielen zu navigieren, wie im folgenden Beispiel gezeigt:

class MyDestination : Fragment() {

    // Type-safe arguments are accessed from the bundle.
    val args by navArgs<MyDestinationArgs>()

    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        view.findViewById<Button>(R.id.next)
            .setOnClickListener {
                // Fragment extension added to retrieve a NavController from
                // any destination.
                findNavController().navigate(R.id.action_to_next_destination)
            }
     }
     ...

}

Palette KTX

Das Palette KTX-Modul bietet idiomatische Kotlin-Unterstützung für die Arbeit mit Farbpaletten.

Wenn Sie dieses Modul verwenden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:

Groovy

dependencies {
    implementation "androidx.palette:palette-ktx:1.0.0"
}

Kotlin

dependencies {
    implementation("androidx.palette:palette-ktx:1.0.0")
}

Wenn Sie beispielsweise mit einer Palette-Instanz arbeiten, können Sie das selected-Farbmuster für ein bestimmtes target mit dem Get-Operator ([ ]) abrufen:

val palette = Palette.from(bitmap).generate()
val swatch = palette[target]

Reactive Streams KTX

Mit dem Reactive Streams KTX-Modul können Sie einen beobachtbaren LiveData-Stream aus einem ReactiveStreams-Publisher erstellen.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1"
}

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1")
}

Angenommen, Sie haben eine Datenbank mit einer kleinen Liste von Nutzern. In Ihrer App laden Sie die Datenbank in den Arbeitsspeicher und zeigen dann Nutzerdaten in der Benutzeroberfläche an. Dazu können Sie RxJava verwenden. Mit der Jetpack-Komponente Room kann die Nutzerliste als Flowable abgerufen werden. In diesem Szenario müssen Sie das Rx-Publisher-Abo auch während der gesamten Lebensdauer Ihres Fragments oder Ihrer Aktivität verwalten.

Mit LiveDataReactiveStreams können Sie jedoch von RxJava und seinen zahlreichen Operatoren und Funktionen zur Arbeitsplanung profitieren und gleichzeitig die Einfachheit von LiveData nutzen, wie im folgenden Beispiel gezeigt:

val fun getUsersLiveData() : LiveData<List<User>> {
    val users: Flowable<List<User>> = dao.findUsers()
    return LiveDataReactiveStreams.fromPublisher(users)
}

Room KTX

Room-Erweiterungen bieten Unterstützung für Coroutinen für Datenbanktransaktionen.

Wenn Sie dieses Modul verwenden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:

Groovy

dependencies {
    implementation "androidx.room:room-ktx:2.7.2"
}

Kotlin

dependencies {
    implementation("androidx.room:room-ktx:2.7.2")
}

Hier sind einige Beispiele dafür, wo Room jetzt Coroutinen verwendet. Im ersten Beispiel wird mit der Funktion suspend eine Liste von User-Objekten zurückgegeben, während im zweiten Beispiel mit Flow von Kotlin die User-Liste asynchron zurückgegeben wird. Wenn Sie Flow verwenden, werden Sie auch über Änderungen in den Tabellen informiert, die Sie abfragen.

@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>

@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>

SQLite KTX

SQLite-Erweiterungen umschließen SQL-bezogenen Code in Transaktionen, wodurch viel Boilerplate-Code entfällt.

Wenn Sie dieses Modul verwenden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:

Groovy

dependencies {
    implementation "androidx.sqlite:sqlite-ktx:2.5.2"
}

Kotlin

dependencies {
    implementation("androidx.sqlite:sqlite-ktx:2.5.2")
}

Hier ein Beispiel für die Verwendung der Erweiterung transaction zum Ausführen einer Datenbanktransaktion:

db.transaction {
    // insert data
}

ViewModel KTX

Die ViewModel KTX-Bibliothek bietet eine viewModelScope()-Funktion, mit der sich Koroutinen einfacher aus Ihrem ViewModel starten lassen. Die CoroutineScope ist an Dispatchers.Main gebunden und wird automatisch gekündigt, wenn die ViewModel gelöscht wird. Sie können viewModelScope() verwenden, anstatt für jede ViewModel einen neuen Bereich zu erstellen.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1"
}

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1")
}

Die folgende viewModelScope()-Funktion startet beispielsweise eine Coroutine, die eine Netzwerkanfrage in einem Hintergrundthread stellt. Die Bibliothek übernimmt die gesamte Einrichtung und das entsprechende Löschen des Bereichs:

class MainViewModel : ViewModel() {
    // Make a network request without blocking the UI thread
    private fun makeNetworkRequest() {
        // launch a coroutine in viewModelScope
        viewModelScope.launch  {
            remoteApi.slowFetch()
            ...
        }
    }

    // No need to override onCleared()
}

WorkManager KTX

WorkManager KTX bietet erstklassige Unterstützung für Coroutinen.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "androidx.work:work-runtime-ktx:2.9.0"
}

Kotlin

dependencies {
    implementation("androidx.work:work-runtime-ktx:2.9.0")
}

Anstatt Worker zu erweitern, können Sie jetzt CoroutineWorker erweitern, das eine etwas andere API hat. Wenn Sie beispielsweise ein einfaches CoroutineWorker erstellen möchten, um einige Netzwerkoperationen auszuführen, können Sie Folgendes tun:

class CoroutineDownloadWorker(context: Context, params: WorkerParameters)
        : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result = coroutineScope {
        val jobs = (0 until 100).map {
            async {
                downloadSynchronously("https://www.google.com")
            }
        }

        // awaitAll will throw an exception if a download fails, which
        // CoroutineWorker will treat as a failure
        jobs.awaitAll()
        Result.success()
    }
}

Weitere Informationen zur Verwendung von CoroutineWorker finden Sie unter Threading in CoroutineWorker.

WorkManager KTX fügt auch Erweiterungsfunktionen für Operations und ListenableFutures hinzu, um die aktuelle Coroutine zu pausieren.

Hier ist ein Beispiel, in dem die von enqueue() zurückgegebene Operation angehalten wird:

// Inside of a coroutine...

// Run async operation and suspend until completed.
WorkManager.getInstance()
        .beginWith(longWorkRequest)
        .enqueue().await()

// Resume after work completes...

Andere KTX-Module

Sie können auch zusätzliche KTX-Module einbinden, die nicht zu AndroidX gehören.

Firebase KTX

Für einige der Firebase SDKs für Android sind Kotlin-Erweiterungsbibliotheken verfügbar, mit denen Sie idiomatischen Kotlin-Code schreiben können, wenn Sie Firebase in Ihrer App verwenden. Weitere Informationen finden Sie in den folgenden Themen:

Google Maps Platform – KTX

Für die Android-SDKs der Google Maps Platform sind KTX-Erweiterungen verfügbar, mit denen Sie verschiedene Kotlin-Sprachfunktionen wie Erweiterungsfunktionen, benannte Parameter, Standardargumente, destrukturierende Deklarationen und Koroutinen nutzen können. Weitere Informationen finden Sie unter den folgenden Links:

Play Core KTX

Play Core KTX bietet Unterstützung für Kotlin-Koroutinen für einmalige Anfragen und Flow für die Überwachung von Statusaktualisierungen. Dazu werden Erweiterungsfunktionen für SplitInstallManager und AppUpdateManager in der Play Core-Bibliothek hinzugefügt.

Fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu, um dieses Modul einzubeziehen:

Groovy

dependencies {
    implementation "com.google.android.play:core-ktx:1.8.1"
}

Kotlin

dependencies {
    implementation("com.google.android.play:core-ktx:1.8.1")
}

Hier ein Beispiel für eine Flow zur Statusüberwachung:

// Inside of a coroutine...

// Request in-app update status updates.
manager.requestUpdateFlow().collect { updateResult ->
    when (updateResult) {
        is AppUpdateResult.Available -> TODO()
        is AppUpdateResult.InProgress -> TODO()
        is AppUpdateResult.Downloaded -> TODO()
        AppUpdateResult.NotAvailable -> TODO()
    }
}

Weitere Informationen

Weitere Informationen zu Android KTX finden Sie in diesem DevBytes-Video.

Wenn Sie ein Problem melden oder eine Funktion vorschlagen möchten, verwenden Sie die Problemverfolgung für Android KTX.