Android KTX Часть Android Jetpack .
Android KTX — это набор расширений Kotlin, входящих в состав Android Jetpack и других библиотек Android. Расширения KTX предоставляют лаконичный и идиоматический код Kotlin для Jetpack, платформы Android и других API. Для этого эти расширения используют ряд возможностей языка Kotlin, включая следующие:
- Функции расширения
- Свойства расширения
- Лямбды
- Именованные параметры
- Значения параметров по умолчанию
- Корутины
Например, при работе с SharedPreferences
необходимо создать редактор, прежде чем вносить изменения в данные настроек. После завершения редактирования необходимо также применить или зафиксировать эти изменения, как показано в следующем примере:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Лямбда-выражения Kotlin идеально подходят для этого случая. Они позволяют использовать более лаконичный подход: передать блок кода для выполнения после создания редактора, дождаться его выполнения, а затем позволить API SharedPreferences
атомарно применить изменения.
Вот пример одной из функций Android KTX Core, SharedPreferences.edit
, которая добавляет функцию редактирования в SharedPreferences
. Эта функция принимает необязательный boolean
флаг в качестве первого аргумента, указывающий, следует ли фиксировать или применять изменения. Она также получает действие для выполнения в редакторе 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) }
Вызывающий может выбрать, следует ли зафиксировать или применить изменения. Лямбда-функция action
сама по себе является анонимной функцией расширения для SharedPreferences.Editor
, которая возвращает Unit
, как указано в её сигнатуре. Поэтому внутри блока вы можете выполнять действия непосредственно над SharedPreferences.Editor
.
Наконец, сигнатура SharedPreferences.edit()
содержит ключевое слово inline
. Это ключевое слово сообщает компилятору Kotlin, что он должен копировать и вставлять (или встраивать ) скомпилированный байт-код функции при каждом её использовании. Это позволяет избежать накладных расходов, связанных с созданием нового класса для каждого action
при каждом вызове функции.
Такая модель передачи кода с использованием лямбда-выражений, применение разумных значений по умолчанию, которые можно переопределить, и добавление этих поведений в существующие API с использованием inline
функций расширения является типичной для улучшений, предоставляемых библиотекой Android KTX.
Используйте Android KTX в своем проекте
Чтобы начать использовать Android KTX, добавьте следующую зависимость в файл build.gradle
вашего проекта:
Круто
repositories { google() }
Котлин
repositories { google() }
Модули AndroidX
Android KTX организован в виде модулей, каждый из которых содержит один или несколько пакетов.
Необходимо включить зависимость для каждого артефакта модуля в файл build.gradle
вашего приложения. Не забудьте добавить номер версии к названию артефакта. Номера последних версий можно найти в соответствующем разделе каждого артефакта в этой теме.
Android KTX содержит одноядерный модуль , который предоставляет расширения Kotlin для общих API-интерфейсов фреймворков и несколько расширений, специфичных для предметной области.
За исключением модуля core, все артефакты модулей KTX заменяют базовую зависимость Java в файле build.gradle
. Например, вы можете заменить зависимость androidx.fragment:fragment
на androidx.fragment:fragment-ktx
. Такой синтаксис помогает лучше управлять версиями и не добавляет дополнительных требований к объявлению зависимостей.
Core KTX
Модуль Core KTX предоставляет расширения для распространённых библиотек, входящих в состав фреймворка Android. Эти библиотеки не имеют зависимостей на базе Java, которые необходимо добавлять в build.gradle
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.core:core-ktx:1.16.0" }
Котлин
dependencies { implementation("androidx.core:core-ktx:1.16.0") }
Вот список пакетов, содержащихся в модуле 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 содержат служебные функции для работы с библиотеками коллекций Android, эффективно использующими память, включая ArrayMap
, LongSparseArray
, LruCache
и другие.
Чтобы использовать этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.collection:collection-ktx:1.5.0" }
Котлин
dependencies { implementation("androidx.collection:collection-ktx:1.5.0") }
Расширения коллекций используют перегрузку операторов Kotlin для упрощения таких задач, как конкатенация коллекций, как показано в следующем примере:
// 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 предоставляет ряд расширений для упрощения API фрагментов.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.8" }
Котлин
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.8") }
С помощью модуля Fragment KTX вы можете упростить транзакции фрагментов с помощью лямбда-выражений, например:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Вы также можете выполнить привязку к ViewModel
в одну строку, используя делегаты свойств viewModels
и 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>()
Жизненный цикл KTX
Lifecycle KTX определяет область LifecycleScope
для каждого объекта Lifecycle
. Любая сопрограмма, запущенная в этой области действия, отменяется при уничтожении Lifecycle
. Доступ к области действия CoroutineScope
Lifecycle
осуществляется с помощью свойств lifecycle.coroutineScope
или lifecycleOwner.lifecycleScope
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.1") }
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.1") }
В следующем примере показано, как использовать lifecycleOwner.lifecycleScope
для асинхронного создания предварительно вычисленного текста:
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
При использовании LiveData может потребоваться асинхронное вычисление значений. Например, вам может потребоваться получить настройки пользователя и передать их в пользовательский интерфейс. Для таких случаев LiveData KTX предоставляет функцию-конструктор liveData
, которая вызывает функцию suspend
и возвращает результат в виде объекта LiveData
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.9.1") }
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.9.1") }
В следующем примере loadUser()
— это функция приостановки, объявленная в другом месте. Вы можете использовать функцию-конструктор liveData
для асинхронного вызова loadUser()
, а затем использовать emit()
для отправки результата:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
Дополнительную информацию об использовании сопрограмм с LiveData
см. в разделе Использование сопрограмм Kotlin с компонентами архитектуры .
Навигация КТХ
Каждый компонент библиотеки навигации имеет собственную версию KTX, которая адаптирует API, делая его более лаконичным и идиоматичным для Kotlin.
Чтобы включить эти модули, добавьте следующее в файл build.gradle
вашего приложения:
классный
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" }
Котлин
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") }
Используйте функции расширения и делегирование свойств для доступа к аргументам назначения и перехода к пунктам назначения, как показано в следующем примере:
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 предлагает идиоматическую поддержку Kotlin для работы с цветовыми палитрами.
Чтобы использовать этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Котлин
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
Например, при работе с экземпляром Palette
вы можете получить selected
образец для заданной target
, используя оператор get ( [ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Реактивные потоки KTX
Модуль Reactive Streams KTX позволяет создать наблюдаемый поток LiveData
от издателя ReactiveStreams
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1") }
В качестве примера предположим базу данных с небольшим списком пользователей. В вашем приложении вы загружаете базу данных в память, а затем отображаете данные пользователей в пользовательском интерфейсе. Для этого можно использовать RxJava . Компонент Room
Jetpack может извлекать список пользователей как Flowable
. В этом сценарии вам также необходимо управлять подпиской издателя Rx на протяжении всего жизненного цикла вашего фрагмента или активности.
Однако с помощью LiveDataReactiveStreams
вы можете воспользоваться преимуществами RxJava и ее богатого набора операторов и возможностей планирования работ, одновременно работая с простотой LiveData
, как показано в следующем примере:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Комната КТХ
Расширения комнат добавляют поддержку сопрограмм для транзакций базы данных.
Чтобы использовать этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.room:room-ktx:2.7.2" }
Котлин
dependencies { implementation("androidx.room:room-ktx:2.7.2") }
Вот несколько примеров, где Room теперь использует сопрограммы. В первом примере используется функция suspend
для возврата списка объектов User
, а во втором — Flow
из Kotlin для асинхронного возврата списка User
. Обратите внимание, что при использовании Flow
вы также получаете уведомления о любых изменениях в запрашиваемых таблицах.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
SQLite KTX
Расширения SQLite заключают код, связанный с SQL, в транзакции, устраняя большую часть шаблонного кода.
Чтобы использовать этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Groovy
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.5.2" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.5.2") }
Вот пример использования расширения transaction
для выполнения транзакции базы данных:
db.transaction {
// insert data
}
ViewModel KTX
Библиотека ViewModel KTX предоставляет функцию viewModelScope()
, которая упрощает запуск сопрограмм из ViewModel
. CoroutineScope
привязана к Dispatchers.Main
и автоматически отменяется при очистке ViewModel
. Вы можете использовать viewModelScope()
вместо создания новой области видимости для каждой ViewModel
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1") }
Например, следующая функция viewModelScope()
запускает сопрограмму, которая выполняет сетевой запрос в фоновом потоке. Библиотека выполняет все настройки и соответствующую очистку области действия:
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 обеспечивает первоклассную поддержку сопрограмм.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.work:work-runtime-ktx:2.10.2" }
Котлин
dependencies { implementation("androidx.work:work-runtime-ktx:2.10.2") }
Вместо расширения Worker
теперь можно расширить CoroutineWorker
, API которого немного отличается. Например, если вы хотите создать простой CoroutineWorker
для выполнения сетевых операций, вы можете сделать следующее:
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()
}
}
Дополнительную информацию об использовании CoroutineWorker
см. в разделе Потоки в CoroutineWorker .
WorkManager KTX также добавляет функции расширения в Operations
и ListenableFutures
для приостановки текущей сопрограммы.
Вот пример, который приостанавливает Operation
, возвращаемую enqueue()
:
// Inside of a coroutine...
// Run async operation and suspend until completed.
WorkManager.getInstance()
.beginWith(longWorkRequest)
.enqueue().await()
// Resume after work completes...
Другие модули KTX
Вы также можете включить дополнительные модули KTX, которые существуют за пределами AndroidX.
Firebase KTX
Некоторые Firebase SDK для Android содержат библиотеки расширений Kotlin, которые позволяют писать идиоматический код Kotlin при использовании Firebase в вашем приложении. Подробнее см. в следующих разделах:
Платформа Google Карт KTX
Для SDK Android платформы Google Карт доступны расширения KTX, которые позволяют использовать ряд возможностей языка Kotlin, таких как функции расширения, именованные параметры и аргументы по умолчанию, объявления деструктуризации и сопрограммы. Подробнее см. в следующих разделах:
Играть в Core KTX
Play Core KTX добавляет поддержку сопрограмм Kotlin для одноразовых запросов и Flow для мониторинга обновлений статуса путем добавления функций расширения в SplitInstallManager
и AppUpdateManager
в библиотеке Play Core.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Круто
dependencies { implementation "com.google.android.play:core-ktx:1.8.1" }
Котлин
dependencies { implementation("com.google.android.play:core-ktx:1.8.1") }
Вот пример 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()
}
}
Дополнительная информация
Чтобы узнать больше об Android KTX, посмотрите видео DevBytes .
Чтобы сообщить о проблеме или предложить функцию, воспользуйтесь системой отслеживания ошибок Android KTX .