Android KTX Część Androida Jetpack.
Android KTX to zestaw rozszerzeń Kotlin, które są dołączone do Jetpacka na Androida i innych bibliotek Androida. Rozszerzenia KTX zapewniają zwięzły, idiomatyczny kod Kotlin dla Jetpack, platformy Android i innych interfejsów API. W tym celu te rozszerzenia wykorzystują kilka funkcji języka Kotlin, w tym:
- Funkcje rozszerzeń
- Właściwości rozszerzenia
- Lambdy
- Parametry nazwane
- Wartości domyślne parametrów
- Współprogramy
Na przykład podczas pracy z SharedPreferences
musisz utworzyć edytującego, zanim będziesz mieć możliwość wprowadzania zmian w danych o ustawieniach. Po zakończeniu edycji musisz też zastosować lub zatwierdzić te zmiany, jak pokazano w tym przykładzie:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Wyrażenia lambda w Kotlinie idealnie pasują do tego przypadku użycia. Umożliwiają one bardziej zwięzłe podejście, ponieważ przekazują blok kodu do wykonania po utworzeniu edytora, pozwalają na wykonanie kodu, a następnie pozwalają interfejsowi SharedPreferences
API na zastosowanie zmian w sposób niepodzielny.
Oto przykład jednej z funkcji Androida KTX Core:SharedPreferences.edit
, która dodaje funkcję edycji do SharedPreferences
. Ta funkcja przyjmuje opcjonalną flagę boolean
jako pierwszy argument, który wskazuje, czy zmiany mają zostać zatwierdzone czy zastosowane. Otrzymuje też działanie do wykonania w SharedPreferences
edytorze w postaci funkcji lambda.
// 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) }
Rozmówca może zdecydować, czy chce zatwierdzić lub zastosować zmiany. Funkcja action
lambda jest anonimową funkcją rozszerzenia w SharedPreferences.Editor
zwracającą Unit
, co wskazuje jej sygnatura. Dlatego w bloku możesz wykonywać działania bezpośrednio na SharedPreferences.Editor
.
Wreszcie SharedPreferences.edit()
podpis zawiera inline
słowo kluczowe.
Ten słowo kluczowe informuje kompilator Kotlin, że powinien kopiować i wklejać (lub wstawiać) skompilowany kod bajtowy funkcji za każdym razem, gdy jest ona używana.
Pozwala to uniknąć obciążenia związanego z tworzeniem nowej klasy za każdym razem, gdy wywoływana jest ta funkcja.action
Ten wzorzec przekazywania kodu za pomocą wyrażeń lambda, stosowania rozsądnych wartości domyślnych, które można zastąpić, i dodawania tych zachowań do istniejących interfejsów API za pomocą inline
funkcji rozszerzających jest typowy dla ulepszeń zapewnianych przez bibliotekę Android KTX.
Używanie Androida KTX w projekcie
Aby zacząć korzystać z Androida KTX, dodaj tę zależność do pliku build.gradle
projektu:
Groovy
repositories { google() }
Kotlin
repositories { google() }
Moduły AndroidX
Android KTX jest podzielony na moduły, a każdy moduł zawiera co najmniej 1 pakiet.
W pliku build.gradle
aplikacji musisz uwzględnić zależność dla każdego artefaktu modułu. Pamiętaj, aby dołączyć numer wersji do artefaktu.
Najnowsze numery wersji znajdziesz w odpowiednich sekcjach tego artykułu.
Android KTX zawiera jeden moduł podstawowy, który udostępnia rozszerzenia Kotlin dla popularnych interfejsów API platformy i kilka rozszerzeń dotyczących konkretnych domen.
Z wyjątkiem modułu podstawowego wszystkie artefakty modułu KTX zastępują podstawową zależność Java w pliku build.gradle
. Możesz na przykład zastąpić zależność androidx.fragment:fragment
zależnością androidx.fragment:fragment-ktx
. Ta składnia ułatwia zarządzanie wersjami i nie wymaga dodatkowych deklaracji zależności.
Core KTX
Moduł Core KTX zawiera rozszerzenia do popularnych bibliotek, które są częścią platformy Android. Te biblioteki nie mają zależności opartych na Javie, które musisz dodać do build.gradle
.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Groovy
dependencies { implementation "androidx.core:core-ktx:1.16.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.16.0") }
Oto lista pakietów zawartych w module Core KTX:
- 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
Collection KTX
Rozszerzenia Collection zawierają funkcje narzędziowe do pracy z wydajnymi pod względem pamięci bibliotekami kolekcji Androida, w tym ArrayMap
, LongSparseArray
, LruCache
i innymi.
Aby użyć tego modułu, dodaj do pliku build.gradle
aplikacji ten ciąg:
Groovy
dependencies { implementation "androidx.collection:collection-ktx:1.5.0" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.5.0") }
Rozszerzenia kolekcji korzystają z przeciążania operatorów w języku Kotlin, aby uprościć takie czynności jak łączenie kolekcji, co widać w tym przykładzie:
// 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
Moduł Fragment KTX zawiera szereg rozszerzeń upraszczających interfejs API fragmentu.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Odlotowe
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.8" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.8") }
Moduł Fragment KTX upraszcza transakcje fragmentów za pomocą np. lambd:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Możesz też powiązać ViewModel
w jednym wierszu, używając delegatów właściwości viewModels
i activityViewModels
:
// 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>()
Cykl życia KTX
Biblioteka Lifecycle KTX definiuje LifecycleScope
dla każdego obiektu Lifecycle
. Każda korutyna uruchomiona w tym zakresie jest anulowana, gdy niszczony jest Lifecycle
. Dostęp do CoroutineScope
elementu Lifecycle
możesz uzyskać za pomocą właściwości lifecycle.coroutineScope
lub lifecycleOwner.lifecycleScope
.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.1") }
Przykład poniżej pokazuje, jak używać lifecycleOwner.lifecycleScope
do asynchronicznego tworzenia wstępnie obliczonego tekstu:
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
Podczas korzystania z LiveData może być konieczne asynchroniczne obliczanie wartości. Możesz na przykład pobrać preferencje użytkownika i wyświetlić je w interfejsie. W takich przypadkach LiveData KTX udostępnia funkcję liveData
, która wywołuje funkcję suspend
i zwraca wynik jako obiekt LiveData
.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.9.1") }
W tym przykładzie loadUser()
to funkcja zawieszania zadeklarowana w innym miejscu.
Możesz użyć funkcji liveData
do wywołania funkcji loadUser()
asynchronicznie, a następnie użyć funkcji emit()
do wyemitowania wyniku:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
Więcej informacji o używaniu współprogramów z LiveData
znajdziesz w artykule Używanie współprogramów Kotlin z komponentami architektury.
Nawigacja KTX
Każdy komponent biblioteki Navigation ma własną wersję KTX, która dostosowuje interfejs API, aby był bardziej zwięzły i zgodny z idiomami języka Kotlin.
Aby uwzględnić te moduły, dodaj do pliku build.gradle
te informacje:
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.9.1" implementation "androidx.navigation:navigation-fragment-ktx:2.9.1" implementation "androidx.navigation:navigation-ui-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.9.1") implementation("androidx.navigation:navigation-fragment-ktx:2.9.1") implementation("androidx.navigation:navigation-ui-ktx:2.9.1") }
Używaj funkcji rozszerzenia i delegowania właściwości, aby uzyskiwać dostęp do argumentów miejsca docelowego i przechodzić do miejsc docelowych, jak pokazano w tym przykładzie:
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
Moduł Palette KTX zapewnia idiomatyczną obsługę Kotlina do pracy z paletami kolorów.
Aby użyć tego modułu, dodaj do pliku build.gradle
aplikacji ten ciąg:
Odlotowe
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
Na przykład podczas pracy z instancją Palette
możesz pobrać próbkę koloru selected
dla danego target
za pomocą operatora get ([ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Reactive Streams KTX
Moduł Reactive Streams KTX umożliwia utworzenie strumienia LiveData
z ReactiveStreams
wydawcy.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1") }
Załóżmy na przykład, że masz bazę danych z krótką listą użytkowników. W aplikacji wczytujesz bazę danych do pamięci, a następnie wyświetlasz dane użytkownika w interfejsie. Aby to osiągnąć, możesz użyć RxJava.
Komponent Room
Jetpack może pobrać listę użytkowników jako Flowable
. W takim przypadku musisz też zarządzać subskrypcją wydawcy Rx
przez cały okres istnienia fragmentu lub aktywności.
Dzięki LiveDataReactiveStreams
możesz jednak korzystać z RxJava i jej bogatego zestawu operatorów oraz funkcji planowania pracy, a jednocześnie pracować z uproszczoną wersją LiveData
, jak pokazano w tym przykładzie:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Room KTX
Rozszerzenia Room dodają obsługę korutyn w transakcjach baz danych.
Aby użyć tego modułu, dodaj do pliku build.gradle
aplikacji ten ciąg:
Groovy
dependencies { implementation "androidx.room:room-ktx:2.7.2" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.7.2") }
Oto kilka przykładów, w których Room używa teraz korutyn. W pierwszym przykładzie używamy funkcji suspend
, aby zwrócić listę obiektów User
, a w drugim wykorzystujemy funkcję Flow
w Kotlinie, aby asynchronicznie zwrócić listę User
. Pamiętaj, że podczas korzystania z Flow
otrzymujesz też powiadomienia o wszelkich zmianach w tabelach, do których wysyłasz zapytania.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
SQLite KTX
Rozszerzenia SQLite otaczają kod związany z SQL transakcjami, co eliminuje wiele powtarzalnych fragmentów kodu.
Aby użyć tego modułu, dodaj do pliku build.gradle
aplikacji ten ciąg:
Odlotowe
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.5.2" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.5.2") }
Oto przykład użycia rozszerzenia transaction
do wykonania transakcji w bazie danych:
db.transaction {
// insert data
}
ViewModel KTX
Biblioteka ViewModel KTX udostępnia funkcję viewModelScope()
, która ułatwia uruchamianie korutyn z poziomu ViewModel
. CoroutineScope
jest powiązany z Dispatchers.Main
i zostanie automatycznie anulowany, gdy ViewModel
zostanie wyczyszczony. Zamiast tworzyć nowy zakres dla każdego ViewModel
, możesz użyć viewModelScope()
.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1") }
Na przykład ta funkcja viewModelScope()
uruchamia korutynę, która wysyła żądanie sieciowe w wątku w tle. Biblioteka obsługuje całą konfigurację i odpowiednie czyszczenie zakresu:
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 zapewnia najwyższej jakości obsługę korutyn.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Odlotowe
dependencies { implementation "androidx.work:work-runtime-ktx:2.10.2" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.10.2") }
Zamiast rozszerzać Worker
, możesz teraz rozszerzać CoroutineWorker
, który ma nieco inny interfejs API. Jeśli na przykład chcesz utworzyć prosty
CoroutineWorker
do wykonywania operacji sieciowych, możesz to zrobić w ten sposób:
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()
}
}
Więcej informacji o używaniu CoroutineWorker
znajdziesz w artykule Wątki w klasie CoroutineWorker.
WorkManager KTX dodaje też funkcje rozszerzające do Operations
i ListenableFutures
, aby zawiesić bieżącą korutynę.
Oto przykład zawieszania Operation
zwracanego przez enqueue()
:
// Inside of a coroutine...
// Run async operation and suspend until completed.
WorkManager.getInstance()
.beginWith(longWorkRequest)
.enqueue().await()
// Resume after work completes...
Inne moduły KTX
Możesz też uwzględnić dodatkowe moduły KTX, które nie należą do AndroidX.
Firebase KTX
Niektóre pakiety SDK Firebase na Androida mają biblioteki rozszerzeń Kotlin, które umożliwiają pisanie idiomatycznego kodu Kotlin podczas korzystania z Firebase w aplikacji. Więcej informacji znajdziesz w tych artykułach:
Google Maps Platform KTX
Dostępne są rozszerzenia KTX dla pakietów SDK Google Maps Platform na Androida, które umożliwiają korzystanie z kilku funkcji języka Kotlin, takich jak funkcje rozszerzające, nazwane parametry i argumenty domyślne, deklaracje destrukcyjne i korutyny. Więcej informacji znajdziesz w tych artykułach:
Play Core KTX
Play Core KTX dodaje obsługę korutyn Kotlin dla jednorazowych żądań i Flow do monitorowania aktualizacji stanu przez dodanie funkcji rozszerzających do SplitInstallManager
i AppUpdateManager
w bibliotece Play Core.
Aby uwzględnić ten moduł, dodaj do pliku build.gradle
ten ciąg:
Groovy
dependencies { implementation "com.google.android.play:core-ktx:1.8.1" }
Kotlin
dependencies { implementation("com.google.android.play:core-ktx:1.8.1") }
Oto przykład monitorowania stanu Flow
:
// 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()
}
}
Więcej informacji
Więcej informacji o Androidzie KTX znajdziesz w filmie DevBytes.
Aby zgłosić problem lub zaproponować funkcję, użyj narzędzia Issue Tracker Androida KTX.