0Pricing
Android Academy · Lekcja

Dlaczego warto stosować Paging

Koszt wczytywania wszystkiego naraz

Dlaczego warto stosować Paging to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 4 lekcji w sumie.

Wczytywanie wszystkiego jest kosztowne

Wyobraź sobie kanał z 50 000 elementów. Jeśli pobierzesz je wszystkie naraz i przechowasz w pamięci, zmarnujesz pamięć, spowolnisz sieć i zamrozisz interfejs podczas analizowania odpowiedzi.

Większość użytkowników przewija tylko kilka pierwszych ekranów. Stronicowanie oznacza wczytywanie danych w małych porcjach (stronach) podczas przewijania, zamiast pobierania wszystkiego z góry.

Problem w kodzie

Naive podejście ładuje całą listę do pamięci. Nawet jeśli serwer to obsługuje, odpowiedź może być ogromna, a sparsowana lista zajmuje większość sterty.

Ten wzorzec nie skaluje się i w przypadku dużych zbiorów danych grozi wystąpieniem OutOfMemoryError.

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

Jak wygląda strona

Strona to niewielki fragment zbioru danych, często zawierający 20–50 elementów. Serwer zwraca jedną stronę oraz wskaźnik do następnej strony (liczbę, offset lub token).

Aplikacja przechowuje w pamięci tylko kilka stron i usuwa starsze, gdy użytkownik przewija dalej.

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

Poznajemy Paging 3

Paging 3 to biblioteka Jetpack, która zajmuje się za Państwa wszystkimi trudnymi aspektami stronicowania:

  • pobieraniem następnej strony, gdy użytkownik zbliża się do końca listy
  • przechowywaniem w pamięci tylko określonego zakresu elementów
  • udostępnianiem stanów ładowania i błędów
  • wbudowaną obsługą coroutines, Flow i Jetpack Compose

Dodawanie zależności

Paging 3 jest dostarczany jako osobne artefakty: środowisko uruchomieniowe oraz integracja z Compose. Należy dodać je w pliku build.gradle.kts modułu.

Artefakt paging-compose udostępnia pomocnicze funkcje dla LazyColumn.

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

Trzy podstawowe elementy

Paging 3 opiera się na trzech typach, których będą Państwo używać wielokrotnie:

  • PagingSource - wie, jak załadować jedną stronę ze źródła
  • Pager - konfiguruje i tworzy strumień stronicowanych danych
  • PagingData - kontener na elementy emitowany jako Flow

W kolejnych lekcjach utworzymy każdy z tych elementów.

PagingData i Flow

Repozytorium udostępnia obiekt Flow<PagingData<T>>. Interfejs użytkownika go zbiera i renderuje aktualnie załadowane elementy.

Nie trzeba samodzielnie tworzyć pełnej listy - Paging dostarcza elementy do interfejsu użytkownika na żądanie.

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 steruje zakresem danych

PagingConfig dostraja sposób ładowania i przechowywania danych przez Paging:

  • pageSize - liczba elementów w żądaniu strony
  • prefetchDistance - odległość od krawędzi, przy której należy uruchomić kolejne ładowanie
  • enablePlaceholders - wyświetlanie miejsc zastępczych dla elementów, które nie zostały jeszcze załadowane
  • maxSize - limit elementów przechowywanych w pamięci
import androidx.paging.PagingConfig

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

Sieć lub baza danych — albo oba źródła

PagingSource może pobierać dane z interfejsu REST API, bazy Room lub dowolnego niestandardowego źródła.

Aby uzyskać prawdziwe działanie offline-first, należy połączyć oba źródła za pomocą RemoteMediator (omówionego w ostatniej lekcji): sieć wypełnia lokalną bazę danych, a interfejs użytkownika pobiera strony z tej bazy.

Płynne przewijanie i mniejsze zużycie pamięci

Dzięki stronicowaniu przewijanie pozostaje płynne, ponieważ każde żądanie jest niewielkie, a zakres danych w pamięci jest ograniczony przez maxSize.

Wskaźniki ładowania i błędów są dostępne bez dodatkowego kodu dzięki LoadState, więc mogą Państwo wyświetlić na dole pokrętło ładowania lub przycisk ponowienia bez ręcznego zarządzania stanem.

// 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()
}

Kiedy potrzebne jest stronicowanie

Warto sięgnąć po Paging 3, gdy:

  • zbiór danych jest duży lub nieograniczony (kanały, wyniki wyszukiwania, historia czatu)
  • dane pochodzą z sieciowego API, które zwraca strony lub kursory
  • potrzebują Państwo automatycznego interfejsu ładowania i błędów oraz kontroli zużycia pamięci

W przypadku krótkiej, stałej listy (na przykład menu ustawień) zwykły LazyColumn jest prostszy i w zupełności wystarczający.

Szybkie sprawdzenie

Jaka jest główna korzyść z używania Paging 3 w przypadku dużej listy?

Podsumowanie: dlaczego Paging

Dowiedzieli się Państwo, dlaczego jednoczesne ładowanie wszystkiego pogarsza wydajność i zwiększa zużycie pamięci oraz jak Paging 3 rozwiązuje ten problem.

  • Dane są ładowane na żądanie w małych stronach podczas przewijania
  • Trzy podstawowe elementy to PagingSource, Pager i PagingData
  • PagingConfig dostraja rozmiar strony, wstępne pobieranie i zakres danych w pamięci
  • Paging integruje się z coroutines, Flow i Compose oraz bez dodatkowego kodu udostępnia stany ładowania i błędów

Następnie: tworzenie elementu PagingSource i podłączanie go do Pager.

Często zadawane pytania

Czy lekcja „Dlaczego warto stosować Paging” jest bezpłatna?

Tak — pełny tekst „Dlaczego warto stosować Paging” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Dlaczego warto stosować Paging”?

Koszt wczytywania wszystkiego naraz Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Android Academy?

Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Dlaczego warto stosować Paging”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?

Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dlaczego warto stosować Paging
  2. PagingSource i Pager
  3. Paging na listach Compose
  4. RemoteMediator i buforowanie
← Powrót do Android Academy