Android Academy · Lektion

Varför Paging

Kostnaden för att läsa in allt på en gång.

Lektion 1 av 413 steg

Varför Paging är en gratis lektion i Android Academy på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Android Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Android Academy innehåller totalt 4 lektioner.

Det är dyrt att läsa in allt

Föreställ Er ett flöde med 50 000 objekt. Om Ni hämtar och håller alla på en gång slösar Ni minne, gör nätverket långsammare och låser gränssnittet medan svaret tolkas.

De flesta användare scrollar bara genom de första skärmarna. Paging innebär att data läses in i små delar (sidor) allt eftersom användaren scrollar, i stället för allt på en gång.

Problemet i koden

En naiv lösning läser in hela listan i minnet. Även om servern stöder detta kan svaret vara enormt, och den tolkade listan tar upp större delen av heapen.

Det här mönstret skalar inte och riskerar OutOfMemoryError för stora datamängder.

// Anti-pattern: load the whole table at once
suspend fun loadAllArticles(): List<Article> {
    // Could be tens of thousands of rows / megabytes of JSON
    return api.getArticles(limit = 50_000)
}

// UI holds ALL of them in memory at once
val articles = loadAllArticles()
LazyColumn {
    items(articles) { article -> ArticleRow(article) }
}

Så här ser en sida ut

En sida är en liten delmängd av datamängden, ofta 20–50 objekt. Servern returnerar en sida samt en pekare till nästa sida (ett nummer, en offset eller en token).

Appen behåller bara några få sidor i minnet och kastar bort gamla sidor när användaren har rullat förbi dem.

data class ArticlePage(
    val items: List<Article>,
    val nextKey: Int?   // null means no more pages
)

// Example REST call returning one page
suspend fun getArticlePage(page: Int, size: Int = 20): ArticlePage

Möt Paging 3

Paging 3 är Jetpack-biblioteket som hanterar alla svåra delar av sidindelning åt Er:

  • Begär nästa sida när användaren närmar sig slutet av listan
  • Behåller bara ett fönster av objekt i minnet
  • Exponerar tillstånd för inläsning och fel
  • Inbyggt stöd för coroutines, Flow och Jetpack Compose

Lägga till beroendet

Paging 3 levereras som separata artefakter: en runtime samt en Compose-integrering. Lägg till dem i modulens build.gradle.kts.

Artefakten paging-compose ger Er hjälpmedel för LazyColumn.

// build.gradle.kts (module)
dependencies {
    val pagingVersion = "3.3.6"
    implementation("androidx.paging:paging-runtime:$pagingVersion")
    implementation("androidx.paging:paging-compose:$pagingVersion")
}

De tre centrala delarna

Paging 3 kretsar kring tre typer som Ni kommer att använda om och om igen:

  • PagingSource – vet hur en sida läses in från en källa
  • Pager – konfigurerar och skapar en dataström med sidindelade data
  • PagingData – behållaren för objekt som skickas ut som en Flow

Vi bygger var och en av dessa i de kommande lektionerna.

PagingData och Flow

Ditt repository exponerar en Flow<PagingData<T>>. Användargränssnittet samlar in den och återger de objekt som för närvarande har lästs in.

Ni behöver aldrig sätta ihop hela listan själva – Paging strömmar objekt till användargränssnittet vid behov.

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import kotlinx.coroutines.flow.Flow

class ArticleRepository(private val api: ArticleApi) {
    fun articles(): Flow<PagingData<Article>> = Pager(
        config = PagingConfig(pageSize = 20)
    ) {
        ArticlePagingSource(api)
    }.flow
}

PagingConfig styr fönstret

PagingConfig finjusterar hur Paging läser in och behåller data:

  • pageSize – antal objekt per sidförfrågan
  • prefetchDistance – hur nära kanten nästa inläsning ska utlösas
  • enablePlaceholders – visa platshållarplatser för objekt som ännu inte har lästs in
  • maxSize – högsta antal objekt som får behållas i minnet
import androidx.paging.PagingConfig

val config = PagingConfig(
    pageSize = 20,
    prefetchDistance = 5,
    enablePlaceholders = false,
    maxSize = 100
)

Nätverk eller databas – eller båda

En PagingSource kan hämta data från ett REST-API, en Room-databas eller valfri anpassad källa.

För en verkligt offline-först-upplevelse kombinerar Ni de två med en RemoteMediator (som behandlas i den sista lektionen): nätverket fyller en lokal databas och användargränssnittet läser sidor från den databasen.

Jämn rullning, mindre minne

Med sidindelning förblir rullningen jämn eftersom varje förfrågan är liten och fönstret i minnet begränsas av maxSize.

Indikatorer för inläsning och fel tillhandahålls automatiskt via LoadState, så Ni kan visa en laddningsindikator längst ned eller en knapp för att försöka igen utan manuell hantering.

// LoadState exposes loading/error per direction
when (val state = adapterLoadState.append) {
    is LoadState.Loading -> showBottomSpinner()
    is LoadState.Error -> showRetry(state.error)
    is LoadState.NotLoading -> hideBottomSpinner()
}

När behöver Ni sidindelning

Använd Paging 3 när:

  • Datamängden är stor eller obegränsad (flöden, sökresultat, chatthistorik)
  • Data kommer från ett nätverks-API som returnerar sidor eller cursors
  • Ni vill ha automatisk status för inläsning/fel och kontroll över minnesanvändningen

För en kort, fast lista (till exempel en inställningsmeny) är en vanlig LazyColumn enklare och fungerar utmärkt.

Snabbtest

Vad är den främsta fördelen med att använda Paging 3 för en stor lista?

Sammanfattning: varför sidindelning

Ni har lärt Er varför det försämrar prestanda och minnesanvändning att läsa in allt på en gång, och hur Paging 3 löser problemet.

  • Data läses in i små sidor medan användaren rullar
  • De tre centrala delarna är PagingSource, Pager och PagingData
  • PagingConfig finjusterar sidstorlek, förinläsning och minnesfönstret
  • Paging integreras med coroutines, Flow och Compose och tillhandahåller status för inläsning/fel automatiskt

Nästa steg: bygga en PagingSource och koppla in den i en Pager.

Gratis att börja

Lär dig Kotlin med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
36
Lektioner
152

Vanliga frågor

Är lektionen ”Varför Paging” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Android Academy, inklusive ”Varför Paging”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Android Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Varför Paging”?

Kostnaden för att läsa in allt på en gång. Ni övar på Android Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Android Academy?

Du behöver inga förkunskaper. Utbildningen i Android Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Varför Paging”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Android Academy-lektionen?

Ja. Varje Android Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Varför Paging
  2. PagingSource och Pager
  3. Paging i Compose-listor
  4. RemoteMediator och cachning
← Tillbaka till Android Academy