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 添加了一个修改函数。此函数将可选的 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 文件中:

repositories {
        google()
    }
    

Android KTX 组织成模块,其中每个模块包含一个或多个软件包。

您必须在应用的 build.gradle 文件中为每个模块工件添加一个依赖项。请务必在工件后面附上版本号。例如,如果您使用 core-ktx 模块,则完整的依赖项与以下代码类似:

dependencies {
        implementation 'androidx.core:core-ktx:1.0.1'
    }
    

模块

Android KTX 包含一个核心模块,该模块可为通用框架 API 提供 Kotlin 扩展程序,还能提供一些领域专用的扩展程序。

除了核心模块之外,所有 KTX 模块工件都会替换 build.gradle 文件中的底层 Java 依赖项。例如,您可以将 androidx.fragment:fragment 依赖项替换为 androidx.fragment:fragment-ktx。此语法有助于更好地管理版本控制,而不会增加额外的依赖项声明要求。

Core KTX

Core KTX 模块为属于 Android 框架的通用库提供扩展程序。这些库没有您需要添加到 build.gradle 的基于 Java 的依赖项。

下面列出了 Core KTX 模块中包含的软件包:

Fragment KTX

依赖项androidx.fragment:fragment-ktx:$version。请务必定义 $version 或将其替换为字面量值。

Fragment KTX 模块可提供许多扩展程序来简化 Fragment API。例如,您可以使用 lambda 来简化 Fragment 事务:

fragmentManager().commit {
       addToBackStack("...")
       setCustomAnimations(
               R.anim.enter_anim,
               R.anim.exit_anim)
       add(fragment, "...")
    }
    

您还可以使用 viewModelsactivityViewModels 属性委托在一行中绑定到 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>()
    

Palette KTX

依赖项androidx.palette:palette-ktx:$version。请务必定义 $version 或将其替换为字面量值。

Palette KTX 模块为使用调色板提供惯用的 Kotlin 支持。

例如,在使用 Palette 实例时,您可以使用 get 运算符 ([ ]) 来检索给定 targetselected 色样:

val palette = Palette.from(bitmap).generate()
    val swatch = palette[target]
    

SQLite KTX

依赖项androidx.sqlite:sqlite-ktx:$version。请务必定义 $version 或将其替换为字面量值。

SQLite 扩展程序将与 SQL 相关的代码封装在事务中,从而消除了大量的样板代码,如以下示例所示:

db.transaction {
        // insert data
    }
    

Collection KTX

依赖项androidx.collection:collection-ktx:$version。请务必定义 $version 或将其替换为字面量值。

Collection 扩展程序包含在 Android 的节省内存的集合库中使用的效用函数,包括 ArrayMapLongParseArrayLruCache 等等。

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
    

ViewModel KTX

依赖项androidx.lifecycle:lifecycle-viewmodel-ktx:$version。请定义或替换 $version 以反映最新的模块版本。

ViewModel KTX 库提供了一个 viewModelScope() 函数,可让您更轻松地从 ViewModel 启动协程CoroutineScope 限定为 Dispatchers.Main,并且会在清除 ViewModel 后自动取消。您可以使用 viewModelScope() 而不是为每个 ViewModel 创建一个新范围。

举例来说,以下 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()
    }
    

Reactive Streams KTX

依赖项androidx.lifecycle:lifecycle-reactivestreams-ktx:$version。请务必定义 $version 或将其替换为字面量值。

Reactive Streams KTX 模块可让您根据 ReactiveStreams 发布程序来创建可观察的 LiveData 流。

举例来说,假设一个数据库只有很少的用户。在您的应用中,您将该数据库加载到内存中,然后在界面中显示用户数据。为此,您可以使用 RxJavaRoom Jetpack 组件能以 Flowable 的形式检索用户列表。在这种情况下,您还必须在 Fragment 或 Activity 的整个生命周期内管理 Rx 发布程序订阅。

不过,借助 LiveDataReactiveStreams,您可以受益于 RxJava 及其丰富的运算符和工作安排功能,同时还能利用 LiveData 的简单性。举例来说,以下代码段根据 RxJava Flowable 发布程序创建了一个可观察的流:

val fun getUsersLiveData() : LiveData<List<User>> {
        val users: Flowable<List<User>> = dao.findUsers()
        return LiveDataReactiveStreams.fromPublisher(users)
    }
    

依赖项

  • androidx.navigation:navigation-runtime-ktx:$version
  • androidx.navigation:navigation-fragment-ktx:$version
  • androidx.navigation:navigation-ui-ktx:$version

请务必定义 $version 或将其替换为字面量值。

Navigation 库的每个组件都有其自己的 KTX 版本,调整 API 以使其更简洁且更符合 Kotlin 的语言习惯。

您可以使用扩展函数和属性委托来访问目标参数并导航到目标,如以下示例所示:

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)
                }
         }
         ...

    }
    

WorkManager KTX

依赖项androidx.work:work-runtime-ktx:$version。请务必定义 $version 或将其替换为字面量值。

WorkManager KTX 通过向 OperationsListenableFutures 添加扩展函数以暂停当前协程,添加了对 Kotlin 协程的支持,如以下示例所示:

// Inside of a coroutine...

    // Run async operation and suspend until completed.
    WorkManager.getInstance()
            .beginWith(longWorkRequest)
            .enqueue().await()

    // Resume after work completes...
    

Play Core KTX

依赖项com.google.android.play:core-ktx:$version。请务必定义 $version 或将其替换为字面量值。

Play Core KTX 通过向 Play Core 库中的 SplitInstallManagerAppUpdateManager 添加扩展函数,针对单发请求和用于监控状态更新的流添加了对 Kotlin 协程的支持。

// 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 问题跟踪器