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): ArticlePagePoznajemy 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 stronyprefetchDistance- odległość od krawędzi, przy której należy uruchomić kolejne ładowanieenablePlaceholders- wyświetlanie miejsc zastępczych dla elementów, które nie zostały jeszcze załadowanemaxSize- 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
PagingConfigdostraja 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
- Dlaczego warto stosować Paging
- PagingSource i Pager
- Paging na listach Compose
- RemoteMediator i buforowanie