Android KTX 是 Android Jetpack 的一部分。
Android KTX 是一套包含在 Android Jetpack 和其他 Android 库中的 Kotlin 扩展程序。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
添加了一个 edit 函数。此函数将其第一个参数作为可选的 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
依赖项替换为 androidx.fragment:fragment-ktx
。此语法有助于更好地管理版本控制,并且不会增加额外的依赖项声明要求。
核心 KTX
核心 KTX 模块为 Android 框架中包含的常用库提供扩展程序。这些库没有您需要添加到 build.gradle
中的基于 Java 的依赖项。
要包含此模块,请将以下内容添加到应用的 build.gradle
文件中:
Groovy
dependencies { implementation "androidx.core:core-ktx:1.15.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.15.0") }
以下是核心 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
集合扩展程序包含用于处理 Android 的内存高效集合库(包括 ArrayMap
、LongSparseArray
、LruCache
等)的实用程序函数。
要使用此模块,请将以下内容添加到应用的 build.gradle
文件中:
Groovy
dependencies { implementation "androidx.collection:collection-ktx:1.4.5" }
Kotlin
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
Fragment KTX 模块 提供了许多扩展程序,可以简化 Fragment API。
要包含此模块,请将以下内容添加到应用的 build.gradle
文件中:
Groovy
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.5" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.5") }
使用 Fragment KTX 模块,您可以使用 lambda 表达式简化 Fragment 事务,例如:
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.7" }
Kotlin
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 KTX
使用 LiveData 时,您可能需要异步计算值。例如,您可能希望检索用户的偏好设置并将其提供给您的 UI。对于这些情况,LiveData KTX 提供了一个 liveData
构建器函数,该函数调用一个 suspend
函数并将结果作为 LiveData
对象提供。
要包含此模块,请将以下内容添加到应用的 build.gradle
文件中:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" }
Kotlin
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 协程与架构组件一起使用。
Navigation KTX
导航库的每个组件都有其自己的 KTX 版本,该版本使 API 更加简洁并符合 Kotlin 习惯用法。
要包含这些模块,请将以下内容添加到您的应用的 build.gradle
文件中
Groovy
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" }
Kotlin
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
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.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7") }
例如,假设一个包含少量用户列表的数据库。在您的应用中,您将数据库加载到内存中,然后在您的 UI 中显示用户数据。为此,您可以使用 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)
}
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
启动 协程 更容易。该 CoroutineScope
绑定到 Dispatchers.Main
,并在 ViewModel
被清除时自动取消。您可以使用 viewModelScope()
来代替为每个 ViewModel
创建一个新的作用域。
要包含此模块,请将以下内容添加到应用的 build.gradle
文件中:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7" }
Kotlin
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
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
(它具有略微不同的 API),而不是扩展 Worker
。例如,如果您想构建一个简单的 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
的示例,该 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 Maps Platform KTX
Google Maps Platform 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 问题跟踪器。