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-интерфейсов платформы, а также несколько расширений для конкретной предметной области.
За исключением основного модуля, все артефакты модуля 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.15.0" }
Котлин
dependencies { implementation("androidx.core:core-ktx:1.15.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.4.5" }
Котлин
dependencies { implementation("androidx.collection:collection-ktx:1.4.5") }
Расширения коллекций используют преимущества перегрузки операторов 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.4" }
Котлин
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.4") }
С помощью модуля 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.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") }
классный
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") }
В следующем примере показано, как использовать 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 КТХ
При использовании LiveData вам может потребоваться асинхронное вычисление значений. Например, вы можете захотеть получить настройки пользователя и передать их в свой пользовательский интерфейс. Для этих случаев LiveData KTX предоставляет функцию построения liveData
, которая вызывает функцию suspend
и обрабатывает результат как объект LiveData
.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.7") }
классный
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.7") }
В следующем примере 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.8.4" implementation "androidx.navigation:navigation-fragment-ktx:2.8.4" implementation "androidx.navigation:navigation-ui-ktx:2.8.4" }
Котлин
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.8.4") implementation("androidx.navigation:navigation-fragment-ktx:2.8.4") implementation("androidx.navigation:navigation-ui-ktx:2.8.4") }
Используйте функции расширения и делегирование свойств для доступа к аргументам назначения и перехода к местам назначения, как показано в следующем примере:
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.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7") }
классный
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7") }
В качестве примера предположим, что база данных имеет небольшой список пользователей. В своем приложении вы загружаете базу данных в память, а затем отображаете пользовательские данные в своем пользовательском интерфейсе. Для этого вы можете использовать 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.6.1" }
Котлин
dependencies { implementation("androidx.room:room-ktx:2.6.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.4.0" }
Котлин
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.4.0") }
Вот пример использования расширения 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.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7") }
классный
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7" }
Котлин
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7") }
Например, следующая функция 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 обеспечивает первоклассную поддержку сопрограмм.
Чтобы включить этот модуль, добавьте следующее в файл build.gradle
вашего приложения:
классный
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.1" }
Котлин
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.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.
Огневая база КТХ
Некоторые SDK Firebase для Android содержат библиотеки расширений Kotlin, которые позволяют вам писать идиоматический код Kotlin при использовании Firebase в вашем приложении. Для получения дополнительной информации см. следующие темы:
Платформа Google Карт KTX
Для Android SDK платформы Google Maps доступны расширения KTX, которые позволяют вам использовать преимущества некоторых функций языка Kotlin, таких как функции расширения, именованные параметры и аргументы по умолчанию, объявления деструктуризации и сопрограммы. Для получения дополнительной информации см. следующие темы:
Играть в ядро 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 .