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 lambdas מתאימים לתרחיש הזה. הם מאפשרים
גישה תמציתית יותר על ידי העברת קטע קוד להפעלה לאחר שהעורך
מאפשרות לקוד לפעול, ואז מאפשרת ל-API של SharedPreferences
להחיל את השינויים באופן אטומי.
לפניכם דוגמה של אחת מהפונקציות של Android KTX Core:
SharedPreferences.edit
שמוסיפה פונקציית עריכה ל-SharedPreferences
. הפונקציה הזו לוקחת
סימון אופציונלי boolean
כארגומנט הראשון שמציין אם לבצע
או להחיל את השינויים. הוא גם מקבל פעולה לביצוע
עורך SharedPreferences
בצורת lambda.
// 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' שעליו להעתיק ולהדביק (או
inline) קוד הבייט שעבר הידור של הפונקציה בכל פעם שמשתמשים בפונקציה.
כך נמנעת התקורה של יצירת מחלקה חדשה לכל action
קוראים לפונקציה הזו.
הדפוס הזה של העברת קוד באמצעות lambdas, תוך החלת ברירות מחדל הגיוניות
לשנות ולהוסיף את ההתנהגויות האלה לממשקי API קיימים באמצעות inline
פונקציות התוספים הן טיפוסיות לשיפורים שמסופקים על ידי Android KTX
לספרייה.
שימוש ב-Android KTX בפרויקט
כדי להתחיל להשתמש ב-Android KTX, צריך להוסיף את התלות הבאה של הפרויקט
קובץ build.gradle
:
מגניב
repositories { google() }
Kotlin
repositories { google() }
מודולים של AndroidX
Android KTX מסודר במודולים, כאשר כל מודול מכיל אחד או יותר חבילות.
עליך לכלול תלות לכל ארטיפקט של מודול באפליקציה שלך
קובץ build.gradle
. חשוב לזכור להוסיף את מספר הגרסה לפריט המידע שנוצר בתהליך הפיתוח (Artifact).
מספרי הגרסאות העדכניים ביותר מופיעים בקטע המתאים של כל פריט מידע שנוצר בתהליך הפיתוח (Artifact)
בנושא הזה.
Android KTX מכיל מודול ליבה יחיד שמספק Kotlin עבור ממשקי API נפוצים של framework ומספר תוספים ספציפיים לדומיין.
פרט למודול הליבה, כל ארטיפקטים של מודול KTX מחליפים את
התלות של Java בקובץ build.gradle
. לדוגמה, אפשר:
החלפה של תלות ב-androidx.fragment:fragment
ב-
androidx.fragment:fragment-ktx
. התחביר הזה עוזר לנהל טוב יותר
ניהול גרסאות ולא מוסיפה דרישות להצהרת תלות.
Core KTX
מודול Core KTX מספק תוספים לספריות נפוצות שהן חלק
המסגרת של Android. בספריות האלה אין יחסי תלות מבוססי Java
יש להוסיף אל build.gradle
.
כדי לכלול את המודול הזה, יש להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.core:core-ktx:1.13.1" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.13.1") }
רשימה של החבילות שכלולות במודול 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
אוסף KTX
תוספי האוספים כוללים פונקציות שימושיות לעבודה עם
ספריות אוספים חסכוניות בזיכרון, כולל ArrayMap
, LongSparseArray
,
LruCache
ואחרים.
כדי להשתמש במודול הזה, צריך להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.collection:collection-ktx:1.4.3" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.4.3") }
תוספי קולקציות מנצלים את עומס יתר של מפעיל של 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
מודול Fragment KTX מספק כמה תוספים כדי לפשט את ה-API למקטעים.
כדי לכלול את המודול הזה, יש להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.2" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.2") }
עם מודול Fragment KTX אפשר לפשט עסקאות עם מקטעים עם lambdas, לדוגמה:
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>()
KTX של מחזור חיים
בשיטה KTX מחזור החיים מוגדר LifecycleScope
לכל
אובייקט Lifecycle
. כל קורוטין
שהופעל בהיקף הזה מבוטל כשה-Lifecycle
מושמד. אפשר
לגשת אל CoroutineScope
של Lifecycle
באמצעות
lifecycle.coroutineScope
או lifecycleOwner.lifecycleScope
.
כדי לכלול את המודול הזה, יש להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4") }
הדוגמה הבאה ממחישה איך להשתמש ב-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, יכול להיות שיהיה צורך לחשב את הערכים באופן אסינכרוני. עבור
לדוגמה, ייתכן שתרצו לאחזר את ההעדפות של המשתמש ולהציג אותן
ממשק משתמש. במקרים כאלה, LiveData KTX מספק פונקציית builder מסוג liveData
,
קוראת לפונקציה suspend
וממלאת את התוצאה כאובייקט LiveData
.
כדי לכלול את המודול הזה, יש להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.4") }
בדוגמה הבאה, loadUser()
היא פונקציית השעיה שהוצהרה במקום אחר.
אפשר להשתמש בפונקציית ה-builder 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-idiomatic.
כדי לכלול את המודולים האלה, צריך להוסיף את המודולים הבאים לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.7.7" implementation "androidx.navigation:navigation-fragment-ktx:2.7.7" implementation "androidx.navigation:navigation-ui-ktx:2.7.7" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.7.7") implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") implementation("androidx.navigation:navigation-ui-ktx:2.7.7") }
שימוש בפונקציות התוסף ובהענקת גישה לנכסים כדי לגשת ליעד ארגומנטים וניווט ליעדים, כפי שמוצג בדוגמה הבאה:
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
מודול KTX של Palette מציעה תמיכה אידיומטית ב-Kotlin לעבודה עם לוחות צבעים.
כדי להשתמש במודול הזה, צריך להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
לדוגמה, כשעובדים עם מכונה של Palette
, אפשר לאחזר את הפונקציה
דוגמית selected
של target
נתון באמצעות אופרטור get ([ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
KTX של סטרימינג תגובתי
מודול KTX של Reactive Streams מאפשר ליצור זרם LiveData
גלוי מ-
בעל אפליקציה ב-ReactiveStreams
.
כדי לכלול את המודול הזה, יש להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.4") }
לדוגמה, נניח שיש לכם מסד נתונים עם רשימה קטנה של משתמשים. באפליקציה שלכם,
לטעון את מסד הנתונים לזיכרון ואז להציג את נתוני המשתמש בממשק המשתמש. כדי להשיג
אפשר להשתמש ב-RxJava.
אפשר לאחזר את רכיב ה-Jetpack Room
את רשימת המשתמשים בתור 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
של האפליקציה:
מגניב
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
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" }
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
של האפליקציה:
מגניב
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
של האפליקציה:
מגניב
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.1" }
Kotlin
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
זמין במאמר
Threading ב-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.
Firebase KTX
לחלק מערכות ה-SDK של Firebase ל-Android יש ספריות תוספים של Kotlin מאפשרות לכתוב קוד Kotlin אידיומטי כשמשתמשים ב-Firebase באפליקציה שלכם. עבור למידע נוסף, ראו את הנושאים הבאים:
פלטפורמה של מפות Google KTX
יש תוספי KTX שזמינים לערכות SDK של הפלטפורמה של מפות Google ל-Android, מאפשרות לנצל מספר תכונות שפה של Kotlin, כמו פונקציות, פרמטרים בעלי שם וארגומנטים שמוגדרים כברירת מחדל, השמדה של הצהרות, וקורוטינים. אפשר למצוא מידע נוסף בנושאים הבאים:
הפעלה של Core KTX
הוספת תמיכה ב-Play Core KTX באמצעות קורוטינים של Kotlin עם בקשות וזרימה אחת
למעקב אחרי עדכוני סטטוס באמצעות הוספת פונקציות של תוספים
SplitInstallManager
וגם AppUpdateManager
בספריית הליבה של Play.
כדי לכלול את המודול הזה, יש להוסיף את הקוד הבא לקובץ build.gradle
של האפליקציה:
מגניב
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