Android KTX Część stanowiąca część Androida Jetpack.
KTX na Androidzie to zestaw rozszerzeń Kotlin, które są dołączone do Jetpacka i innych bibliotek Androida. Rozszerzenia KTX zapewniają zwięzłe, idiomatyczne interfejsy API Kotlin dla Jetpacka, platformy Android i innych interfejsów API. Te rozszerzenia wykorzystują kilka funkcji języka Kotlin, między innymi:
- Funkcje rozszerzeń
- Właściwości rozszerzenia
- Lambda
- Parametry nazwane
- Domyślne wartości parametrów
- Kortyny
Na przykład w przypadku korzystania z SharedPreferences
przed wprowadzeniem zmian w danych dotyczących preferencji musisz utworzyć edytor. 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
W tym przypadku idealnie nadają się lambda Kotlin. Pozwalają one przyjąć bardziej zwięzłe podejście przez przekazanie bloku kodu do wykonania po utworzeniu edytora, zezwolenie na wykonanie kodu i zezwolenie interfejsowi API SharedPreferences
na atomowe stosowanie zmian.
Oto przykład jednej z funkcji Android KTX Core (SharedPreferences.edit
), która dodaje funkcję edycji do elementu SharedPreferences
. Pierwszym argumentem tej funkcji jest opcjonalna flaga boolean
, która wskazuje, czy zmiany mają zostać zatwierdzone, czy zastosowane. Otrzymuje też działanie do wykonania w edytorze SharedPreferences
w postaci 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) }
Element wywołujący może wybrać, czy chce zatwierdzić zmiany, czy je zastosować. Lambda action
jest samą anonimową funkcją rozszerzenia w SharedPreferences.Editor
, która zwraca wartość Unit
, jak wskazuje jej podpis. Dzięki temu możesz wykonywać pracę bezpośrednio w panelu SharedPreferences.Editor
.
Podpis SharedPreferences.edit()
zawiera słowo kluczowe inline
.
To słowo kluczowe informuje kompilator Kotlin, że powinien kopiować i wklejać (lub wbudować) skompilowany kod bajtowy funkcji za każdym razem, gdy jest używana.
Pozwala to uniknąć konieczności tworzenia instancji nowej klasy dla każdego elementu action
przy każdym wywołaniu tej funkcji.
Ten wzorzec przekazywania kodu za pomocą funkcji lambda, stosowanie rozsądnych wartości domyślnych, które można zastąpić, i dodawanie tych zachowań do istniejących interfejsów API za pomocą funkcji rozszerzeń inline
jest typowym z ulepszeń zapewnianych przez bibliotekę KTX Androida.
Użyj KTX Androida w projekcie
Aby zacząć korzystać z KTX Androida, dodaj tę zależność do pliku build.gradle
w Twoim projekcie:
Odlotowy
repositories { google() }
Kotlin
repositories { google() }
Moduły AndroidX
KTX Androida jest podzielony na moduły, z których każdy zawiera co najmniej 1 pakiet.
W pliku build.gradle
aplikacji musisz umieścić zależność każdego artefaktu modułu. Pamiętaj, aby dołączyć do artefaktu numer wersji.
Najnowsze numery wersji znajdziesz w odpowiednich sekcjach tego tematu.
KTX na Androidzie zawiera moduł jednordzeniowy, który zapewnia rozszerzenia Kotlin dla typowych interfejsów API platformy oraz kilka rozszerzeń specyficznych dla domeny.
Z wyjątkiem modułu głównego wszystkie artefakty modułu KTX zastępują bazową zależność Javy w pliku build.gradle
. Zależność androidx.fragment:fragment
możesz na przykład zastąpić wartością androidx.fragment:fragment-ktx
. Ta składnia pomaga lepiej zarządzać obsługą wersji i nie dodaje dodatkowych wymagań dotyczących deklaracji zależności.
Core KTX
Moduł Core KTX zawiera rozszerzenia popularnych bibliotek, które są częścią platformy Androida. Te biblioteki nie mają zależności opartych na Javie, które trzeba dodać do build.gradle
.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.core:core-ktx:1.13.1" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.13.1") }
Oto lista pakietów, które znajdują się 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.widz,
Kolekcja KTX
Rozszerzenia kolekcji zawierają przydatne funkcje umożliwiające pracę z bibliotekami zbierającymi efektywne pamięć Androida, takimi jak ArrayMap
, LongSparseArray
czy LruCache
.
Aby korzystać z tego modułu, dodaj do pliku build.gradle
swojej aplikacji:
Odlotowy
dependencies { implementation "androidx.collection:collection-ktx:1.4.0" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.4.0") }
Rozszerzenia kolekcji wykorzystują przeciążenie operatora Kotlin, aby uprościć np. łączenie zbiorów, jak 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ń, które upraszczają interfejs API fragmentów.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.fragment:fragment-ktx:1.7.0" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.7.0") }
Dzięki modułowi KTX fragmentu kodu możesz uprościć transakcje fragmentowe za pomocą lambda, np.:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Możesz też powiązać obiekt ViewModel
w jednym wierszu, używając przedstawicieli 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
Cykl życia KTX definiuje LifecycleScope
dla każdego obiektu Lifecycle
. Każda współpraca uruchomiona w tym zakresie zostanie anulowana po zniszczeniu 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 następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.7.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0") }
Ten przykład pokazuje, jak za pomocą lifecycleOwner.lifecycleScope
asynchronicznie tworzyć wstępnie obliczony tekst:
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ć ustawienia użytkownika i wyświetlić je w swoim interfejsie. W takich przypadkach LiveData KTX udostępnia funkcję kreatora liveData
, która wywołuje funkcję suspend
i wyświetla wynik jako obiekt LiveData
.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0") }
W poniższym przykładzie loadUser()
to funkcja zawieszania zadeklarowana w innym miejscu.
Za pomocą funkcji konstruktora liveData
możesz asynchronicznie wywoływać metodę loadUser()
, a potem generować wynik za pomocą metody emit()
:
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 na temat używania współprogramów Kotlin z komponentami architektury.
Nawigacja KTX
Każdy komponent biblioteki nawigacji ma własną wersję KTX, która dostosowuje interfejs API, aby był bardziej zwięzły i kotlin-idiomatyczny.
Aby uwzględnić te moduły, dodaj te elementy do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.7.7" implementation "androidx.navigation:navigation-fragment-ktx:2.7.7" implementation "androidx.navigation:navigation-ui-ktx:2.7.7" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.7.7") implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") implementation("androidx.navigation:navigation-ui-ktx:2.7.7") }
Za pomocą funkcji rozszerzeń i przekazywania właściwości możesz uzyskiwać dostęp do argumentów miejsc docelowych 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)
}
}
...
}
Paleta KTX
Moduł Palette KTX zapewnia idiomatyczną obsługę platformy Kotlin w zakresie pracy z paletami kolorów.
Aby korzystać z tego modułu, dodaj do pliku build.gradle
swojej aplikacji:
Odlotowy
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ę selected
dla danego elementu target
za pomocą operatora get ([ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Reaktywne strumienie KTX
Moduł KTX strumieni reaktywnych umożliwia utworzenie obserwowanego strumienia LiveData
od wydawcy ReactiveStreams
.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.7.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.7.0") }
Załóżmy na przykład, że tworzysz bazę danych z niewielką listą użytkowników. W aplikacji wczytujesz bazę danych do pamięci, a potem wyświetlasz dane użytkownika w interfejsie. Możesz do tego użyć RxJava.
Komponent Jetpack Room
może pobierać listę użytkowników w postaci Flowable
. W takiej sytuacji musisz też zarządzać subskrypcją wydawcy Rx przez cały okres aktywności fragmentu lub aktywności.
Dzięki LiveDataReactiveStreams
możesz jednak korzystać z funkcji RxJava, jej bogatego zestawu operatorów i harmonogramu pracy, a także z łatwością funkcji LiveData
, jak pokazano w tym przykładzie:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Pokój KTX
Rozszerzenia dotyczące pokoi dodają obsługę transakcji do bazy danych.
Aby korzystać z tego modułu, dodaj do pliku build.gradle
swojej aplikacji:
Odlotowy
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.6.1") }
Oto kilka przykładów sytuacji, w których funkcja Room używa teraz współprogramów. W pierwszym przykładzie użyto funkcji suspend
do zwrócenia listy obiektów User
, a w drugim funkcji Flow
Kotlina do asynchronicznego zwracania listy User
. Pamiętaj, że podczas korzystania z tabeli Flow
będziesz też otrzymywać powiadomienia o wszelkich zmianach w tabelach, których dotyczy zapytanie.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
SQLite KTX
Rozszerzenia SQLite opakowują kod związany z SQL w transakcjach, eliminując mnogość kodu.
Aby korzystać z tego modułu, dodaj do pliku build.gradle
swojej aplikacji:
Odlotowy
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.4.0" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.4.0") }
Oto przykład użycia rozszerzenia transaction
do wykonania transakcji w bazie danych:
db.transaction {
// insert data
}
ViewModel KTX
Biblioteka KTX ViewModel udostępnia funkcję viewModelScope()
, która ułatwia uruchamianie korekty z ViewModel
. CoroutineScope
jest powiązany z Dispatchers.Main
i jest automatycznie anulowany po wyczyszczeniu ViewModel
. Możesz użyć właściwości viewModelScope()
, zamiast tworzyć nowy zakres dla każdej ViewModel
.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") }
Na przykład ta funkcja viewModelScope()
uruchamia współprogram, który wysyła żądanie sieciowe w wątku w tle. Biblioteka obsługuje całą konfigurację i odpowiadające jej 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 klasy pomoc w zakresie współprogramów.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.0" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.0") }
Zamiast rozszerzać zakres Worker
, możesz teraz rozszerzyć rozszerzenie CoroutineWorker
, który ma nieco inny interfejs API. Jeśli na przykład chcesz utworzyć prostą CoroutineWorker
do wykonywania niektórych operacji sieciowych, możesz wykonać te czynności:
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 korzystaniu z CoroutineWorker
znajdziesz w artykule o wątkach w CoroutineWorker.
WorkManager KTX dodaje też funkcje rozszerzenia do Operations
i ListenableFutures
, aby zawiesić bieżącą współpracę.
Oto przykład, który powoduje zawieszenie działania Operation
zwracanego przez metodę 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ż dołączyć dodatkowe moduły KTX, które istnieją poza AndroidemX.
KTX Firebase
Niektóre pakiety SDK Firebase na Androida zawierają biblioteki rozszerzeń Kotlin, które umożliwiają pisanie idiomatycznego kodu Kotlin podczas korzystania z Firebase w aplikacji. Więcej informacji znajdziesz w tych tematach:
Google Maps Platform KTX
W pakietach SDK Google Maps Platform na Androida dostępne są rozszerzenia KTX, które pozwalają korzystać z kilku funkcji języka Kotlin, takich jak funkcje rozszerzeń, parametry nazwane i argumenty domyślne, deklaracje niszczycielskie oraz współprogramy. Więcej informacji można znaleźć w następujących tematach:
Zagraj w Core KTX
Play Core KTX dodaje obsługę współprogramów Kotlin w przypadku żądań typu „one-shot” oraz przepływa do monitorowania aktualizacji stanu – dodaliśmy funkcje rozszerzeń do SplitInstallManager
i AppUpdateManager
w bibliotece podstawowej Play.
Aby uwzględnić ten moduł, dodaj następującą treść do pliku build.gradle
aplikacji:
Odlotowy
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
Aby dowiedzieć się więcej o KTX na Androidzie, obejrzyj film o DevBytes.
Aby zgłosić problem lub zaproponować nową funkcję, skorzystaj z narzędzia Android KTX do śledzenia problemów.