סקירה כללית של ספריית Paging   בארגז הכלים Android Jetpack.

ספריית Paging עוזרת לכם לטעון ולהציג דפי נתונים ממערך נתונים גדול יותר, מאחסון מקומי או דרך רשת. כך האפליקציה יכולה להשתמש ברוחב הפס של הרשת ובמשאבי המערכת בצורה יעילה יותר. הרכיבים של ספריית Paging נועדו להתאים לארכיטקטורה המומלצת של אפליקציות ל-Android, להשתלב בצורה חלקה עם רכיבי Jetpack אחרים ולספק תמיכה מעולה ב-Kotlin.

יתרונות השימוש בספריית Paging

ספריית Paging כוללת את התכונות הבאות:

  • שמירה במטמון בזיכרון של הנתונים בדפים. כך אפשר לוודא שהאפליקציה משתמשת במשאבי המערכת ביעילות בזמן העבודה עם נתונים בדפים.
  • מניעת כפילויות מובנית בבקשות, שעוזרת לוודא שהאפליקציה משתמשת ברוחב הפס של הרשת ובמשאבי המערכת בצורה יעילה.
  • תמיכה מובנית בשגרות המשך (coroutine) של Kotlin, ב-Flows וב-Jetpack Compose.
  • תמיכה מובנית בטיפול בשגיאות, כולל יכולות רענון וניסיון חוזר.
  • כלי בדיקה ייעודיים, כמו TestPager ו-asSnapshot, לאימות מקורות הדפדוף וטרנספורמציות הנתונים.

הגדרה

כדי לייבא רכיבי Paging לאפליקציה ל-Android, מוסיפים את יחסי התלות הבאים לקובץ build.gradle של האפליקציה:

Kotlin

dependencies {
  val paging_version = "3.5.3"

  // Needed for Android Views and LiveData. Optional if only using
  // paging-compose
  implementation("androidx.paging:paging-runtime:$paging_version")

  // Needed to collect PagingData flows in Jetpack Compose
  implementation("androidx.paging:paging-compose:$paging_version")

  // Needed to test PagingSource and PagingData transformations in isolation
  testImplementation("androidx.paging:paging-testing:$paging_version")
}

מגניב

dependencies {
  def paging_version = "3.5.3"

  // Needed for Android Views and LiveData. Optional if only using
  // paging-compose
  implementation "androidx.paging:paging-runtime:$paging_version"

  // Needed to collect PagingData flows in Jetpack Compose
  implementation "androidx.paging:paging-compose:$paging_version"

  // Needed to test PagingSource and PagingData transformations in isolation
  testImplementation "androidx.paging:paging-testing:$paging_version"
}

ארכיטקטורת הספרייה

הרכיבים של ספריית Paging פועלים בשלוש שכבות של האפליקציה:

  • שכבת המאגר
  • שכבת ViewModel
  • שכבת ממשק המשתמש
תמונה שבה מוצגים תזרימי נתונים עם דפים מהרכיבים PagingSource או RemoteMediator בשכבת המאגר לרכיב Pager בשכבת ViewModel.
    לאחר מכן, הרכיב Pager חושף Flow של PagingData לרכיבי הפריסה הלא פעילים בשכבת ממשק המשתמש.
תרשים 1. דוגמה לאופן שבו ספריית Paging משתלבת בארכיטקטורה של האפליקציה.

בקטע הזה מתוארים הרכיבים של ספריית Paging שפועלים בכל שכבה, ואיך הם פועלים יחד כדי לטעון ולהציג נתונים בדפים.

שכבת המאגר

הרכיב הראשי של ספריית Paging בשכבת המאגר הוא PagingSource. כל אובייקט PagingSource מגדיר מקור נתונים ואת האופן שבו הנתונים מאוחזרים ממנו. אובייקט PagingSource יכול לטעון נתונים מכל מקור יחיד, כולל מקורות ברשת ומסדי נתונים מקומיים.

רכיב נוסף של ספריית Paging שאפשר להשתמש בו הוא RemoteMediator. אובייקט RemoteMediator מטפל בדפדוף ממקור נתונים שכבתי, כמו מקור נתונים ברשת עם מטמון של מסד נתונים מקומי.

שכבת ViewModel

הרכיב Pager מספק API ציבורי ליצירת מופעים של PagingData שנחשפים ב-reactive streams, על סמך אובייקט PagingSource ואובייקט הגדרה PagingConfig.

הרכיב שמחבר את שכבת ה-ViewModel לממשק המשתמש הוא PagingData. אובייקט PagingData הוא מאגר לתמונת מצב של נתונים שמחולקים לדפים. היא שולחת שאילתה לאובייקט PagingSource ומאחסנת את התוצאה.

שכבת ממשק המשתמש

ממשק ה-API הראשי של ממשק המשתמש של Paging הוא collectAsLazyPagingItems(). היא חושפת פריטים בדפים כרשימת נתונים שרכיבי הפריסה הלא פעילים של Compose, כמו LazyColumn ו-LazyRow, יכולים לצרוך בקלות.

מוסיפים את הספרייה androidx.paging:paging-compose כדי להשתמש בממשקי API שתואמים ל-Compose, שמאפשרים לממשק המשתמש להגיב באופן אוטומטי לטעינות נתונים, לעדכונים ולשגיאות בלי צורך במתאמים או בלוגיקה של השוואה. משתמשים בפונקציית ההרחבה collectAsLazyPagingItems() ב-Flow<PagingData> כדי להעביר את ה-LazyPagingItems שהוחזר אל items() ב-LazyColumn.

@Composable
fun MessageList(pager: Pager<Int, Message>) {
    val lazyPagingItems = pager.flow.collectAsLazyPagingItems()

    LazyColumn {
        items(
            lazyPagingItems.itemCount,
            key = lazyPagingItems.itemKey { it.id }
        ) { index ->
            val message = lazyPagingItems[index]
            if (message != null) {
                MessageRow(message)
            } else {
                MessagePlaceholder()
            }
        }
    }
}

מידע נוסף זמין במאמר קבוצות נתונים גדולות (עימוד).