Android KTX Część Android Jetpack.
Android KTX to zestaw rozszerzeń Kotlin, które są dołączane do Androida Jetpack i innych bibliotek Androida. Rozszerzenia KTX zapewniają zwięzłe, idiotyczne narzędzie Kotlin do Jetpacka, platformy Android i innych interfejsów API. Wykorzystują one do tego kilka funkcji w języku Kotlin, w tym:
- Funkcje rozszerzeń
- Właściwości rozszerzenia
- Funkcje lambda
- Nazwane parametry
- Domyślne wartości parametru
- Koutyny
Na przykład podczas pracy z SharedPreferences
, zanim zmodyfikujesz dane preferencji, musisz utworzyć edytor. Po zakończeniu edycji musisz też zastosować lub zatwierdzić te zmiany, jak w tym przykładzie:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
W tym przypadku idealnie sprawdzają się lambda Kotlin. Pozwalają one przyjąć bardziej zwięzłe podejście – po utworzeniu edytora przekazują blok kodu do wykonania, a następnie umożliwiają jego wykonanie, a interfejs API SharedPreferences
umożliwia atomowe zastosowanie zmian.
Oto przykład jednej z funkcji SharedPreferences.edit
w Android KTX Core, która dodaje funkcję edycji do SharedPreferences
. Ta funkcja wykorzystuje opcjonalną flagę boolean
jako pierwszy argument, który wskazuje, czy zmiany należy zatwierdzić, czy zastosować. Otrzymuje również działanie w postaci funkcji lambda, aby wykonać działanie w edytorze SharedPreferences
.
// 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 zdecydować, czy zatwierdzić, czy zastosować zmiany. Funkcja action
lambda jest anonimową funkcją rozszerzenia w SharedPreferences.Editor
, która zwraca wartość Unit
zgodnie z jej podpisem. Dlatego właśnie wewnątrz bloku możesz wykonywać tę pracę bezpośrednio w SharedPreferences.Editor
.
Podpis SharedPreferences.edit()
zawiera słowo kluczowe inline
.
To słowo kluczowe informuje kompilator Kotlin, że powinien skopiować i wkleić (lub wbudować) skompilowany kod bajtowy funkcji za każdym razem, gdy jest używana.
Pozwala to uniknąć nakładów związanych z tworzeniem nowej klasy dla każdego elementu action
przy każdym wywołaniu tej funkcji.
Ten wzorzec przekazywania kodu za pomocą parametrów lambda, stosowania rozsądnych wartości domyślnych, które można zastąpić i dodawania tych działań do istniejących interfejsów API za pomocą funkcji rozszerzeń inline
, jest typowym elementem ulepszeń zapewnianych przez bibliotekę Androida KTX.
Użyj Android KTX w swoim projekcie
Aby zacząć używać Androida KTX, dodaj tę zależność do pliku build.gradle
projektu:
Odlotowe
repositories { google() }
Kotlin
repositories { google() }
Moduły AndroidX
Android KTX dzieli się na moduły, z których każdy zawiera co najmniej jeden pakiet.
W pliku build.gradle
aplikacji musisz dodać zależność dla każdego artefaktu modułu. Pamiętaj, aby do artefaktu dołączyć numer wersji.
Najnowsze numery wersji znajdziesz w sekcji odpowiadającej poszczególnym artefaktom w tym temacie.
Android KTX zawiera jedno podstawowy moduł udostępniający rozszerzenia Kotlin do interfejsów API platformy oraz kilka rozszerzeń dla konkretnych domen.
Z wyjątkiem modułu podstawowego wszystkie artefakty modułu KTX zastępują podstawową zależność Javy w pliku build.gradle
. Na przykład możesz zastąpić zależność androidx.fragment:fragment
elementem androidx.fragment:fragment-ktx
. Ta składnia ułatwia zarządzanie wersjami i nie ma dodatkowych wymagań dotyczących deklaracji zależności.
Core KTX
Moduł Core KTX zawiera rozszerzenia do popularnych bibliotek, które wchodzą w skład platformy Androida. Te biblioteki nie mają zależności opartych na Javie, które trzeba dodać do biblioteki build.gradle
.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
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 zawiera moduł 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
Kolekcja KTX
Rozszerzenia kolekcji zawierają funkcje narzędziowe ułatwiające pracę z bibliotekami zbierającymi dane z Androida, które oszczędzają pamięć, w tym ArrayMap
, LongSparseArray
czy LruCache
.
Aby korzystać z tego modułu, do pliku build.gradle
dodaj te elementy:
Odlotowe
dependencies { implementation "androidx.collection:collection-ktx:1.4.3" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.4.3") }
Rozszerzenia kolekcji korzystają z przeciążania operatorów Kotlin, aby uprościć np. łączenie zbiorów, jak pokazano 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ł KTX z fragmentami zawiera szereg rozszerzeń, które upraszczają interfejs API fragment.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Odlotowy
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.2" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.2") }
Dzięki modułowi Fragment KTX możesz uprościć transakcje oparte na fragmentach za pomocą parametrów lambda, np.:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Możesz też powiązać z obiektem ViewModel
w jednym wierszu, korzystając z 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
KTX w cyklu życia definiuje LifecycleScope
dla każdego obiektu Lifecycle
. Każda współprogram uruchamiana w tym zakresie zostaje anulowana po zniszczeniu obiektu Lifecycle
. Aby uzyskać dostęp do elementu CoroutineScope
w: Lifecycle
, możesz użyć właściwości lifecycle.coroutineScope
lub lifecycleOwner.lifecycleScope
.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4") }
Ten przykład pokazuje, jak za pomocą narzędzia lifecycleOwner.lifecycleScope
asynchronicznie utworzyć 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
Korzystanie z LiveData może wymagać asynchronicznego obliczania wartości. Możesz na przykład pobrać preferencje użytkownika i wyświetlać je w Twoim interfejsie. W takich przypadkach LiveData KTX udostępnia funkcję konstruktora liveData
, która wywołuje funkcję suspend
i wyświetla wynik jako obiekt LiveData
.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.4") }
W poniższym przykładzie loadUser()
to funkcja zawieszenia zadeklarowana w innym miejscu.
Za pomocą funkcji konstruktora liveData
możesz wywołać asynchronicznie loadUser()
, a następnie za pomocą emit()
do wygenerowania wyniku:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
Więcej informacji o używaniu współrzędnych z LiveData
znajdziesz w artykule o używaniu współrzędnych Kotlina 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 imitujący kotlin.
Aby je uwzględnić, dodaj do pliku build.gradle
aplikacji te moduły:
Groovy
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 rozszerzenia i przekazywania właściwości możesz uzyskać dostęp do argumentów miejsca docelowego i przejść 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 oferuje idiomatyczne wsparcie Kotlina w pracy z paletami kolorów.
Aby korzystać z tego modułu, do pliku build.gradle
dodaj te elementy:
Odlotowy
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
W przypadku pracy z instancją Palette
możesz na przykład pobrać próbkę selected
dla danego target
miejsca za pomocą operatora get ([ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Transmisje reaktywne KTX
Moduł KTX Reaktywnych strumieni umożliwia utworzenie możliwego do obserwowania strumienia LiveData
od wydawcy ReactiveStreams
.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.4") }
Załóżmy na przykład, że używasz bazy danych z niewielką listą użytkowników. W aplikacji wczytujesz bazę danych do pamięci, a następnie wyświetlasz dane użytkownika w interfejsie. Możesz to zrobić za pomocą RxJava.
Komponent Jetpack Room
może pobierać 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 technologii RxJava oraz jej bogatego zestawu operatorów i funkcji harmonogramu pracy, a jednocześnie korzystać z prostoty interfejsu 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ą współgrające z obsługą transakcji w bazie danych.
Aby korzystać z tego modułu, do pliku build.gradle
dodaj te elementy:
Groovy
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.6.1") }
Oto kilka przykładów, w których Room używa teraz współrzędnych. W pierwszym przykładzie wykorzystywana jest funkcja suspend
, która zwraca listę obiektów User
, a drugi – funkcja Flow
projektu Kotlina, która zwraca asynchronicznie listę User
. Pamiętaj, że gdy używasz Flow
, otrzymasz też 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 zawijają kod związany z SQL w transakcjach, eliminując niepotrzebny powtarzalny kod.
Aby korzystać z tego modułu, do pliku build.gradle
dodaj te elementy:
Odlotowe
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
}
WyświetlModel KTX
Biblioteka ViewModel KTX zawiera funkcję viewModelScope()
, która ułatwia uruchamianie współrzędnych z ViewModel
. CoroutineScope
jest powiązany z Dispatchers.Main
i jest automatycznie anulowany po wyczyszczeniu ViewModel
. Możesz używać funkcji viewModelScope()
, zamiast tworzyć nowy zakres dla każdego obiektu ViewModel
.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4") }
Na przykład ta funkcja viewModelScope()
uruchamia współrzędną, która wysyła żądanie sieciowe w wątku w tle. Biblioteka obsługuje całą konfigurację i czyszczenie odpowiednich zakresów:
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 obsługę współprogramów.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Odlotowy
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.1") }
Zamiast rozszerzenia Worker
możesz rozszerzyć zakres CoroutineWorker
, który ma nieco inny interfejs API. Jeśli na przykład chcesz utworzyć prosty CoroutineWorker
do wykonywania pewnych 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 używaniu CoroutineWorker
znajdziesz w sekcji Wątki w CoroutineWorker.
WorkManager KTX dodaje też funkcje rozszerzeń do Operations
i ListenableFutures
, aby zawiesić bieżącą współrzędną.
Oto przykład zawieszania obiektu 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ż dołączyć dodatkowe moduły KTX, które istnieją poza AndroidemX.
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 tematach:
Google Maps Platform KTX
Dla pakietów SDK Google Maps Platform na Androida są dostępne rozszerzenia KTX, które pozwalają korzystać z kilku funkcji językowych Kotlin, takich jak funkcje rozszerzeń, parametry nazwane i argumenty domyślne, deklaracje destrukcyjne i współrzędne. Więcej informacji znajdziesz w tych tematach:
Odtwórz Core KTX
Play Core KTX obsługuje połączenia Kotlin w żądaniach jednorazowych oraz Flow do monitorowania stanu aktualizacji przez dodanie funkcji rozszerzeń do SplitInstallManager
i AppUpdateManager
w bibliotece Play Core.
Aby uwzględnić ten moduł, do pliku build.gradle
aplikacji dodaj ten kod:
Odlotowe
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 elementu Flow
do monitorowania stanu:
// 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 Androidzie KTX, obejrzyj film DevBytes.
Aby zgłosić problem lub zaproponować funkcję, skorzystaj z narzędzia do zgłaszania problemów z Androidem KTX.