Android KTX 是 Android Jetpack 的一部分。
Android KTX 是一组 Kotlin 扩展,包含在 Android Jetpack 和其他 Android 库中。KTX 扩展为 Jetpack、Android 平台和其他 API 提供简洁、惯用的 Kotlin。为此,这些扩展利用了几个 Kotlin 语言功能,包括以下功能
- 扩展函数
- 扩展属性
- Lambda 表达式
- 命名参数
- 参数默认值
- 协程
例如,在使用 SharedPreferences
时,您必须 创建编辑器 才能修改首选项数据。您还必须在完成编辑后应用或提交这些更改,如下例所示
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Kotlin Lambda 表达式非常适合此用例。它们允许您通过将代码块传递到创建编辑器后执行来采取更简洁的方法,让代码执行,然后让 SharedPreferences
API 原子地应用更改。
以下是 Android KTX Core 函数之一的示例,SharedPreferences.edit
,它将编辑函数添加到 SharedPreferences
。此函数以可选的 boolean
标志作为第一个参数,该标志指示是否提交或应用更改。它还接收一个 Lambda 表达式,用于对 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
实例化新类所带来的开销。
这种使用 Lambda 表达式传递代码、应用可覆盖的合理默认值以及使用 inline
扩展函数将这些行为添加到现有 API 的模式是 Android KTX 库提供的增强功能的典型模式。
在您的项目中使用 Android KTX
要开始使用 Android KTX,请将以下依赖项添加到您的项目 build.gradle
文件中
Groovy
repositories { google() }
Kotlin
repositories { google() }
AndroidX 模块
Android KTX 组织成模块,每个模块包含一个或多个包。
您必须在应用程序的 build.gradle
文件中为每个模块工件包含依赖项。请记住将版本号追加到工件。您可以在本主题中每个工件对应部分找到最新版本号。
Android KTX 包含一个 单一核心模块,它为通用框架 API 提供 Kotlin 扩展,以及几个特定于域的扩展。
除了核心模块之外,所有 KTX 模块工件都会在您的 build.gradle
文件中替换底层 Java 依赖项。例如,您可以用 androidx.fragment:fragment-ktx
替换 androidx.fragment:fragment
依赖项。此语法有助于更好地管理版本控制,并且不会添加额外的依赖项声明要求。
核心 KTX
核心 KTX 模块为 Android 框架的一部分的常用库提供扩展。这些库没有您需要添加到 build.gradle
的基于 Java 的依赖项。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "androidx.core:core-ktx:1.13.1" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.13.1") }
以下是核心 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
集合 KTX
Collection 扩展包含用于处理 Android 内存效率高的集合库的实用程序函数,包括 ArrayMap
、LongSparseArray
、LruCache
等。
要使用此模块,请在您的应用的 build.gradle
文件中添加以下内容
Groovy
dependencies { implementation "androidx.collection:collection-ktx:1.4.3" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.4.3") }
Collection 扩展利用 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
The Fragment KTX 模块 提供了许多扩展来简化片段 API。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.3" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.3") }
使用 Fragment KTX 模块,您可以使用 lambda 简化片段事务,例如
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
您还可以使用 viewModels
和 activityViewModels
属性委托在一行代码中绑定到 ViewModel
// 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
Lifecycle KTX 为每个 Lifecycle
对象定义了一个 LifecycleScope
。在此作用域中启动的任何协程将在 Lifecycle
被销毁时被取消。您可以使用 lifecycle.coroutineScope
或 lifecycleOwner.lifecycleScope
属性访问 Lifecycle
的 CoroutineScope
。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.5" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.5") }
以下示例演示了如何使用 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 时,您可能需要异步计算值。例如,您可能想要检索用户的偏好并将其提供给您的 UI。对于这些情况,LiveData KTX 提供了一个 liveData
构建器函数,该函数调用一个 suspend
函数并将结果作为 LiveData
对象提供。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.5" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.5") }
在以下示例中,loadUser()
是在其他地方声明的挂起函数。您可以使用 liveData
构建器函数异步调用 loadUser()
,然后使用 emit()
发射结果
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
有关使用协程与 LiveData
的更多信息,请参阅 使用 Kotlin 协程与架构组件。
Navigation KTX
导航库的每个组件都有自己的 KTX 版本,该版本调整 API 以使其更简洁且更符合 Kotlin 惯例。
要包含这些模块,请在您的应用的 build.gradle
文件中添加以下内容
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.8.0" implementation "androidx.navigation:navigation-fragment-ktx:2.8.0" implementation "androidx.navigation:navigation-ui-ktx:2.8.0" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.8.0") implementation("androidx.navigation:navigation-fragment-ktx:2.8.0") implementation("androidx.navigation:navigation-ui-ktx:2.8.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
The Palette KTX 模块 提供了针对颜色调色板工作的 Kotlin 风格支持。
要使用此模块,请在您的应用的 build.gradle
文件中添加以下内容
Groovy
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
例如,当使用 Palette
实例时,您可以使用 get 运算符 ([ ]
) 检索给定 target
的 selected
色样。
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Reactive Streams KTX
Reactive Streams KTX 模块允许您从 ReactiveStreams
发布者创建可观察的 LiveData
流。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.5" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.5") }
例如,假设一个包含少量用户列表的数据库。在您的应用中,您将数据库加载到内存中,然后在您的 UI 中显示用户数据。为了实现这一点,您可以使用 RxJava。The Room
Jetpack 组件可以将用户列表检索为 Flowable
。在这种情况下,您还必须在您的片段或活动的整个生命周期中管理 Rx 发布者订阅。
但是,使用 LiveDataReactiveStreams
,您可以从 RxJava 及其丰富的运算符和工作调度功能中受益,同时还可以使用 LiveData
的简便性,如以下示例所示
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Room KTX
Room 扩展为数据库事务添加了协程支持。
要使用此模块,请在您的应用的 build.gradle
文件中添加以下内容
Groovy
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.6.1") }
以下是一些 Room 现在使用协程的示例。第一个示例使用 suspend
函数返回一个 User
对象列表,而第二个示例使用 Kotlin 的 Flow
异步返回 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.4.0" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.4.0") }
以下是如何使用 transaction
扩展执行数据库事务的示例
db.transaction {
// insert data
}
ViewModel KTX
ViewModel KTX 库提供了一个 viewModelScope()
函数,该函数使从您的 ViewModel
启动 协程 变得更加容易。The CoroutineScope
绑定到 Dispatchers.Main
,并在 ViewModel
被清除时自动取消。您可以使用 viewModelScope()
而不是为每个 ViewModel
创建一个新作用域。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5") }
例如,以下 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
文件中
Groovy
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.1") }
您可以现在扩展 CoroutineWorker
,而不是扩展 Worker
,它具有略有不同的 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
的更多信息,请参阅 协程工作者中的线程。
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 模块
您还可以包含存在于 AndroidX 之外的其他 KTX 模块。
Firebase KTX
一些用于 Android 的 Firebase SDK 具有 Kotlin 扩展库,使您能够在您的应用中使用 Firebase 时编写符合 Kotlin 惯例的代码。有关更多信息,请参阅以下主题
Google 地图平台 KTX
Google 地图平台 Android SDK 提供了 KTX 扩展,使您可以利用一些 Kotlin 语言功能,例如扩展函数、命名参数和默认参数、解构声明和协程。有关更多信息,请参阅以下主题
Play Core KTX
Play Core KTX 为 Play Core 库中的 SplitInstallManager
和 AppUpdateManager
添加了扩展函数,从而为一次性请求添加了 Kotlin 协程支持,为监控状态更新添加了 Flow 支持。
要包含此模块,请将以下内容添加到应用程序的 build.gradle
文件中
Groovy
dependencies { implementation "com.google.android.play:core-ktx:1.8.1" }
Kotlin
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 问题跟踪器。