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 核心函式
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
依附元件替換為 androidx.fragment:fragment-ktx
。這個語法不但能促進版本管理,也不必新增其他依附元件宣告要求。
核心 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.3.0" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.3.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
片段 KTX
片段 KTX 模組 提供許多擴充功能來簡化片段 API。
如要加入這個模組,請在應用程式的 build.gradle
檔案中新增以下程式碼:
Groovy
dependencies { implementation "androidx.fragment:fragment-ktx:1.6.2" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.6.2") }
透過 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>()
生命週期 KTX
生命週期 KTX 為每個
Lifecycle
物件定義 LifecycleScope
。刪除 Lifecycle
時,系統會取消在此範圍內啟動的任何協同程式。您可以使用 lifecycle.coroutineScope
或 lifecycleOwner.lifecycleScope
屬性,來存取 Lifecycle
的 CoroutineScope
。
如要加入這個模組,請在應用程式的 build.gradle
檔案中新增以下程式碼:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") }
以下範例說明如何使用 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.6.2" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2") }
在以下範例中,loadUser()
是已在其他位置宣告的暫停函式。您可以使用 liveData
建構工具函式,以非同步方式呼叫 loadUser()
,然後使用 emit()
發出結果:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
如要進一步瞭解如何搭配使用協同程式和 LiveData
,請參閱搭配使用 Kotlin 協同程式和架構元件
的說明。
導覽 KTX
導覽程式庫的每個元件都有自身的 KTX 版本。該版本可將 API 調整為較精簡且符合 Kotlin 的語言習慣。
如要加入這些模組,請在應用程式的 build.gradle
檔案中新增以下程式碼:
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.7.5" implementation "androidx.navigation:navigation-fragment-ktx:2.7.5" implementation "androidx.navigation:navigation-ui-ktx:2.7.5" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.7.5") implementation("androidx.navigation:navigation-fragment-ktx:2.7.5") implementation("androidx.navigation:navigation-ui-ktx:2.7.5") }
使用擴充功能函式和屬性委派項目,即可存取目的地引數並前往目的地,如以下範例所示:
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)
}
}
...
}
區塊面板 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]
回應式串流 KTX
回應式串流 KTX 模組可從 ReactiveStreams
發布者建立可觀測的 LiveData
串流。
如要加入這個模組,請在應用程式的 build.gradle
檔案中新增以下程式碼:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.4") }
例如,假設資料庫中只有一小群使用者。您在應用程式中將資料庫載入記憶體,然後在 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)
}
聊天室 KTX
聊天室擴充功能為資料庫交易加入協同程式支援。
如要使用這個模組,請在應用程式的 build.gradle
檔案中新增以下程式碼:
Groovy
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.6.1") }
以下列舉幾種聊天室目前使用協同程式的情況。第一個範例使用 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.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4") }
例如,以下 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.0" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.0") }
現在您不必擴充
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
,以暫停當前的協同程式。
以下範例說明如何暫停
enqueue()
傳回的
Operation
:
// 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
中新增擴充功能函式,藉此針對一次性要求和用於監控狀態更新的 Flow,新增 Kotlin 協同程式的支援功能。
如要加入這個模組,請在應用程式的 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 Issue Tracker 。