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
lambda само по себе является анонимной функцией расширения в 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 предоставляет расширения для общих библиотек, которые являются частью фреймворка 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.анимация
- 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.текст
- androidx.core.transition
- androidx.core.util
- androidx.core.view
- androidx.core.виджет
Коллекция КТХ
Расширения 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>()
Жизненный цикл КТХ
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.0" implementation "androidx.navigation:navigation-fragment-ktx:2.9.0" implementation "androidx.navigation:navigation-ui-ktx:2.9.0" }
Котлин
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.9.0") implementation("androidx.navigation:navigation-fragment-ktx:2.9.0") implementation("androidx.navigation:navigation-ui-ktx:2.9.0") }
Используйте функции расширения и делегирование свойств для доступа к аргументам назначения и перехода к пунктам назначения, как показано в следующем примере:
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
вашего приложения:
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1") }
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.9.1" }
Котлин
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.1" }
Котлин
dependencies { implementation("androidx.room:room-ktx:2.7.1") }
Вот несколько примеров, где 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
вашего приложения:
классный
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.5.1" }
Котлин
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.5.1") }
Вот пример использования расширения transaction
для выполнения транзакции базы данных:
db.transaction {
// insert data
}
Просмотр модели KTX
Библиотека ViewModel KTX предоставляет функцию viewModelScope()
, которая упрощает запуск сопрограмм из ViewModel
. CoroutineScope
привязана к Dispatchers.Main
и автоматически отменяется при очистке ViewModel
. Вы можете использовать viewModelScope()
вместо создания новой области видимости для каждой ViewModel
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1") }
Круто
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.1" }
Котлин
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.1" }
Котлин
dependencies { implementation("androidx.work:work-runtime-ktx:2.10.1") }
Вместо расширения 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
Для Google Maps Platform Android SDK доступны расширения 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 .