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 nutzen diese Erweiterungen mehrere Kotlin-Sprachfunktionen, darunter:
- Erweiterungsfunktionen
- Erweiterungseigenschaften
- 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 Einstellungsdaten vornehmen können. Sie müssen diese Änderungen auch anwenden oder per Commit übernehmen, 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 sind für diesen Anwendungsfall perfekt geeignet. Sie ermöglichen einen prägnanteren Ansatz, indem Sie einen Codeblock übergeben, der nach dem Erstellen des Editors ausgeführt wird. Der Code wird ausgeführt und die SharedPreferences API wendet die Änderungen dann atomar an.
Hier ist ein Beispiel für eine der Android KTX Core-Funktionen, SharedPreferences.edit, die SharedPreferences eine Bearbeitungsfunktion hinzufügt. Diese Funktion akzeptiert 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 Aufrufer kann entscheiden, ob die Änderungen übernommen oder angewendet werden sollen. Der Lambda-Ausdruck action ist selbst eine anonyme Erweiterungsfunktion für SharedPreferences.Editor, die Unit zurückgibt, wie durch die Signatur angegeben. Aus diesem Grund können Sie im Block die Arbeit direkt am SharedPreferences.Editor ausführen.
Schließlich enthält die Signatur SharedPreferences.edit() das Schlüsselwort inline.
Dieses Keyword teilt dem Kotlin-Compiler mit, dass er den kompilierten Bytecode für die Funktion bei jeder Verwendung der Funktion kopieren und einfügen (oder inline) soll.
Dadurch wird der Aufwand für die Instanziierung einer neuen Klasse für jede action bei jedem Aufruf dieser Funktion vermieden.
Dieses Muster, bei dem Code mithilfe von Lambdas übergeben wird, sinnvolle Standardeinstellungen angewendet werden, die überschrieben werden können, und diese Verhaltensweisen mithilfe von inline-Erweiterungsfunktionen zu vorhandenen APIs hinzugefügt werden, ist typisch für die Verbesserungen, die die Android KTX-Bibliothek bietet.
Android KTX in Ihrem Projekt verwenden
Wenn Sie Android KTX verwenden möchten, fügen Sie der build.gradle-Datei Ihres Projekts die folgende Abhängigkeit hinzu:
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 in der build.gradle-Datei Ihrer App eine Abhängigkeit für jedes Modulartefakt angeben. Denken Sie daran, die Versionsnummer an das Artefakt anzuhängen.
Die aktuellen Versionsnummern finden Sie im entsprechenden Abschnitt des jeweiligen Artefakts in diesem Thema.
Android KTX enthält ein einzelnes Kernmodul, das Kotlin-Erweiterungen für gängige Framework-APIs und mehrere domänenspezifische Erweiterungen bietet.
Mit Ausnahme des Kernmoduls ersetzen alle KTX-Modulartefakte 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 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 zu build.gradle hinzufügen müssen.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.core:core-ktx:1.19.1" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.19.1") }
Hier ist eine Liste der Pakete, die im Core KTX-Modul enthalten sind:
- androidx.core.animation
- androidx.core.content
- androidx.core.content.res
- androidx.core.database
- androidx.core.database.sqlite
- androidx.core.graphics
- androidx.core.graphics.drawable
- androidx.core.location
- androidx.core.net
- androidx.core.os
- androidx.core.text
- androidx.core.transition
- androidx.core.util
- androidx.core.view
- androidx.core.widget
KTX-Sammlung
Die Sammlungserweiterungen enthalten Dienstfunktionen für die Arbeit mit den speichereffizienten Sammlungsbibliotheken von Android, darunter ArrayMap, LongSparseArray, LruCache und andere.
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.6.0" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.6.0") }
Sammlungserweiterungen nutzen die Operatorüberladung von Kotlin, um beispielsweise die Verkettung 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, um die Fragment API zu vereinfachen.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Cool
dependencies { implementation "androidx.fragment:fragment-ktx:1.9.1" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.9.1") }
Mit dem Fragment-KTX-Modul können Sie Fragmenttransaktionen mit Lambdas vereinfachen, zum Beispiel:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Sie können auch in einer Zeile eine Bindung an ein ViewModel herstellen, indem Sie die Attribut-Delegates 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 einen LifecycleScope für jedes Lifecycle-Objekt. Jede in diesem Bereich gestartete Koroutine wird abgebrochen, wenn die Lifecycle gelöscht wird. Sie können mit den Attributen lifecycle.coroutineScope oder lifecycleOwner.lifecycleScope auf die CoroutineScope der Lifecycle zugreifen.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.11.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.11.0") }
Das folgende Beispiel zeigt, wie Sie mit lifecycleOwner.lifecycleScope asynchron vorkalkulierten Text 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 können 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.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.11.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.11.0") }
Im folgenden Beispiel ist loadUser() eine an anderer Stelle deklarierte Sperrfunktion.
Sie können die Builder-Funktion liveData verwenden, um loadUser() asynchron aufzurufen, und dann emit() verwenden, um das Ergebnis auszugeben:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
Weitere Informationen zur Verwendung von Koroutinen mit LiveData finden Sie unter Kotlin-Koroutinen mit Architekturkomponenten verwenden.
Navigation KTX
Jede Komponente der Navigationsbibliothek hat eine eigene KTX-Version, die die API so anpasst, dass sie prägnanter und Kotlin-idiomatischer ist.
Wenn Sie diese Module einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.10.2" implementation "androidx.navigation:navigation-fragment-ktx:2.10.2" implementation "androidx.navigation:navigation-ui-ktx:2.10.2" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.10.2") implementation("androidx.navigation:navigation-fragment-ktx:2.10.2") implementation("androidx.navigation:navigation-ui-ktx:2.10.2") }
Verwenden Sie die Erweiterungsfunktionen und die Attributdelegierung, 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:
Cool
dependencies { implementation "androidx.palette:palette-ktx:1.1.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.1.0") }
Wenn Sie beispielsweise mit einer Palette-Instanz arbeiten, können Sie das selected-Swatch 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 KTX-Modul für Reactive Streams können Sie einen beobachtbaren LiveData-Stream aus einem ReactiveStreams-Publisher erstellen.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.11.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.11.0") }
Nehmen wir als Beispiel 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.
Die Jetpack-Komponente Room kann die Nutzerliste als Flowable abrufen. In diesem Szenario müssen Sie auch das Rx-Publisher-Abo während der Lebensdauer Ihres Fragments oder Ihrer Aktivität verwalten.
Mit LiveDataReactiveStreams können Sie jedoch von RxJava und den 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 Koroutinen 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.8.5" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.8.5") }
Hier sind einige Beispiele, in denen Room jetzt Koroutinen verwendet. Im ersten Beispiel wird eine suspend-Funktion verwendet, um eine Liste von User-Objekten zurückzugeben. Im zweiten Beispiel wird die Flow-Funktion von Kotlin verwendet, um die User-Liste asynchron zurückzugeben. Wenn Sie Flow verwenden, werden Sie auch über Änderungen in den Tabellen benachrichtigt, 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 verpacken 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.7.1" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.7.1") }
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 über Ihr ViewModel starten lassen. Der CoroutineScope ist an Dispatchers.Main gebunden und wird automatisch abgebrochen, wenn der ViewModel gelöscht wird. Sie können viewModelScope() verwenden, anstatt für jede ViewModel einen neuen Bereich zu erstellen.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.11.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.11.0") }
Die folgende viewModelScope()-Funktion startet beispielsweise eine Koroutine, die eine Netzwerkanfrage in einem Hintergrundthread stellt. Die Bibliothek übernimmt die gesamte Einrichtung und die entsprechende Bereichslöschung:
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 Koroutinen.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
Groovy
dependencies { implementation "androidx.work:work-runtime-ktx:2.12.0" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.12.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 Netzwerkvorgänge auszuführen, können Sie so vorgehen:
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 außerdem Erweiterungsfunktionen zu Operations und ListenableFutures hinzu, um die aktuelle Koroutine zu sperren.
Hier ist ein Beispiel, in dem die von enqueue() zurückgegebene Operation gesperrt 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 außerhalb von AndroidX vorhanden sind.
Firebase KTX
Einige der Firebase SDKs für Android enthalten Kotlin-Erweiterungsbibliotheken, 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 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 zu SplitInstallManager und AppUpdateManager in der Play Core-Bibliothek hinzugefügt.
Wenn Sie dieses Modul einbinden möchten, fügen Sie der Datei build.gradle Ihrer App Folgendes hinzu:
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 einen 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 im DevBytes-Video.
Wenn Sie ein Problem melden oder eine Funktion vorschlagen möchten, verwenden Sie den Android KTX Issue Tracker.