Android Academy · leksjon

Hurtigbufring og ytelse

Grunnleggende om hurtigbufring i minne og på disk.

Leksjon 3 av 413 trinn

Hurtigbufring og ytelse er en gratis leksjon i Android Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Android Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Android Academy inneholder totalt 4 leksjoner.

Hvorfor hurtigbufring er viktig

Nedlasting og dekoding av et bilde er ressurskrevende: Det bruker båndbredde, batteri og CPU. Hvis du laster ned det samme bildet på nytt hver gang en liste rulles, oppleves appen som treg, og den bruker unødvendig mye data.

Hurtigbufring lagrer dekodede bilder og nedlastede byte, slik at neste forespørsel nesten blir umiddelbar. Coil leveres som standard med to hurtigbuffere: et hurtigbuffer i minnet (raskt, dekodede bitmaps) og et hurtigbuffer på disken (varig, rå byte).

Denne leksjonen forklarer hvordan de fungerer, og hvordan du kan finjustere dem.

To lag: minne og disk

Coil sjekker hurtigbufferne i denne rekkefølgen:

  • Hurtigbuffer i minnet: inneholder nylig brukte, dekodede bitmaps i RAM. Et treff her er umiddelbart, og dekoding er ikke nødvendig.
  • Hurtigbuffer på disken: lagrer de opprinnelig nedlastede byt­ene på enheten. Et treff her gjør at nettverket kan hoppes over, men bildet må fortsatt dekodes.
  • Nettverk: den langsomme banen, som bare brukes når begge hurtigbufferne ikke har treff.

Minne er raskt, men begrenset, og tømmes når appen avsluttes. Diskplassen er større og beholdes når appen startes på nytt.

Konfigurere ImageLoader

Hurtigbufferne ligger på ImageLoader, motoren bak alle forespørsler. Vanligvis bygger du én egendefinert loader og bruker den på nytt. Her setter vi størrelsen på hurtigbufferet i minnet til en prosentandel av tilgjengelig RAM og hurtigbufferet på disken til en fast mengde byte.

En singleton-loader unngår dupliserte hurtigbuffere og unødvendig minnebruk.

import android.content.Context
import coil3.ImageLoader
import coil3.disk.DiskCache
import coil3.memory.MemoryCache
import okio.Path.Companion.toOkioPath

fun newImageLoader(context: Context): ImageLoader =
    ImageLoader.Builder(context)
        .memoryCache {
            MemoryCache.Builder()
                .maxSizePercent(context, 0.25) // 25% of app RAM
                .build()
        }
        .diskCache {
            DiskCache.Builder()
                .directory(context.cacheDir.resolve("image_cache").toOkioPath())
                .maxSizeBytes(50L * 1024 * 1024) // 50 MB
                .build()
        }
        .build()

Tilordne en singleton-loader

Coil 3 lar deg angi én loader for hele applikasjonen ved å implementere SingletonImageLoader.Factory i Application-klassen. Deretter bruker alle AsyncImage-forekomster den automatisk, slik at du slipper å sende med en loader hver gang.

import android.app.Application
import coil3.ImageLoader
import coil3.PlatformContext
import coil3.SingletonImageLoader

class MyApp : Application(), SingletonImageLoader.Factory {
    override fun newImageLoader(context: PlatformContext): ImageLoader =
        ImageLoader.Builder(context)
            .crossfade(true)
            .build()
}

Sty­ring av hurtigbufferregler

Hver forespørsel kan slå hurtigbufring av eller på med memoryCachePolicy og diskCachePolicy. Reglene er ENABLED, READ_ONLY, WRITE_ONLY eller DISABLED.

Du kan for eksempel deaktivere hurtigbufferet i minnet for svært store engangsbilder som du ikke vil beholde i RAM, eller deaktivere hurtigbufferet på disken for sensitivt innhold.

import android.content.Context
import coil3.request.CachePolicy
import coil3.request.ImageRequest

fun noMemoryCacheRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        .memoryCachePolicy(CachePolicy.DISABLED)
        .diskCachePolicy(CachePolicy.ENABLED)
        .build()

Endre størrelse: Ikke dekodér enorme bitmaps

Den klart største ytelsesfeilen er å dekode et bilde på 4000x3000 piksler til et miniatyrbilde på 100dp. Det sløser med både minne og tid. Som standard tilpasser Coil bitmapen til de målte grensene til composable-en, slik at en liten AsyncImage dekoder en liten bitmap.

Du kan tvinge frem en bestemt mål­størrelse med size() i forespørselen når du kjenner dimensjonene.

import android.content.Context
import coil3.request.ImageRequest
import coil3.size.Size

fun thumbnailRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        .size(Size(200, 200)) // decode at most 200x200
        .build()

Stabile hurtigbuffer­nøkler

Coil utleder en hurtigbuffer­nøkkel fra dataene i forespørselen. Hvis URL-ene dine inneholder parametere som endres (for eksempel et signert token), får identiske bilder forskjellige nøkler og treffer aldri hurtigbufferet.

Angi eksplisitte memoryCacheKey- og diskCacheKey-verdier basert på den stabile delen, for eksempel bilde-ID-en, slik at hurtigbufring fungerer.

import android.content.Context
import coil3.request.ImageRequest

fun stableKeyRequest(context: Context, id: String, signedUrl: String) =
    ImageRequest.Builder(context)
        .data(signedUrl)
        .memoryCacheKey("image_$id")
        .diskCacheKey("image_$id")
        .build()

Forhåndslaste bilder

For en jevnere opplevelse kan du varme opp hurtigbufferet før et bilde vises, for eksempel ved å forhåndslaste neste side i en feed. Bruk loaderens enqueue med en forespørsel som ikke har noe mål.

Når brukeren kommer til bildet, ligger det allerede i hurtigbufferet og vises umiddelbart.

import android.content.Context
import coil3.ImageLoader
import coil3.request.ImageRequest

fun preload(context: Context, loader: ImageLoader, urls: List<String>) {
    urls.forEach { url ->
        val request = ImageRequest.Builder(context)
            .data(url)
            .build()
        loader.enqueue(request)
    }
}

Tømme hurtigbufferet

Av og til trenger du å frigjøre plass eller tvinge frem en oppdatering, for eksempel etter at brukeren har oppdatert profilbildet sitt. Du kan tømme hurtigbufferet i minnet, hurtigbufferet på disken eller fjerne én enkelt nøkkel.

Det er ressurskrevende å tømme alt, så foretrekk å fjerne bestemte nøkler når du kan.

import coil3.ImageLoader
import coil3.memory.MemoryCache

fun refreshAvatar(loader: ImageLoader, key: String) {
    // Remove one entry so the next load refetches
    loader.memoryCache?.remove(MemoryCache.Key(key))
    loader.diskCache?.remove(key)
}

fun clearAll(loader: ImageLoader) {
    loader.memoryCache?.clear()
    // Disk clearing is heavier; do it sparingly
}

Crossfade kontra treff i hurtigbufferet

Crossfade ser flott ut ved lasting fra nettverket, men kan føles tregt når et bilde kommer direkte fra hurtigbufferet i minnet og kunne ha blitt vist umiddelbart. Coil håndterer dette intelligent: Som standard hopper det over crossfade-animasjonen ved treff i minnehurtigbufferet og animerer bare bilder som faktisk er lastet inn.

Dermed får du jevne overganger ved første lasting og umiddelbar visning når du ruller gjennom bufrede bilder, uten at du trenger å gjøre noe ekstra.

import android.content.Context
import coil3.request.ImageRequest
import coil3.request.crossfade

fun feedRequest(context: Context, url: String) =
    ImageRequest.Builder(context)
        .data(url)
        // Crossfade plays on real loads; memory-cache hits show instantly
        .crossfade(true)
        .build()

Ytelsessjekkliste for lister

Når du viser mange bilder i en LazyColumn eller et rutenett, bør du følge disse reglene for jevn rulling:

  • Gi hvert bilde en fast størrelse, slik at Coil dekoder en liten bitmap.
  • Bruk én singleton-ImageLoader på nytt, slik at hurtigbufferne deles.
  • Bruk ContentScale.Crop for å unngå forskyvninger i oppsettet.
  • Hold hurtigbuffer­nøklene stabile mellom omlastinger.
  • La Coil avbryte forespørsler utenfor skjermen automatisk – ikke motarbeid dette.
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import coil3.compose.AsyncImage

@Composable
fun PhotoGrid(urls: List<String>) {
    LazyVerticalGrid(columns = GridCells.Fixed(3)) {
        items(urls) { url ->
            AsyncImage(
                model = url,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier.aspectRatio(1f)
            )
        }
    }
}

Hurtigsjekk

Coil sjekker hurtigbufferne før den bruker nettverket. Hvilket hurtigbuffer er raskest ved treff, fordi det hopper over dekodingen helt?

Oppsummering

Du har lært hvordan Coil holder bilder raske:

  • To hurtigbuffere: minne (dekodet, raskt, lite) og disk (rå byte, varig, større).
  • Konfigurer størrelsene på en egendefinert ImageLoader, og gjør én tilgjengelig via SingletonImageLoader.Factory.
  • Finjuster oppførselen per forespørsel med memoryCachePolicy og diskCachePolicy.
  • Dekodér alltid i visningsstørrelsen, og angi eksplisitt size() ved behov.
  • Bruk stabile hurtigbuffer­nøkler, forhåndslast kommende bilder, og fjern bestemte nøkler for å oppdatere.

neste: ta steget videre fra bilder til avspilling av lyd og video.

Gratis å komme i gang

Lær deg Kotlin med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
36
Leksjoner
152

Ofte stilte spørsmål

Er leksjonen «Hurtigbufring og ytelse» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Android Academy, inkludert «Hurtigbufring og ytelse», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Android Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Hurtigbufring og ytelse»?

Grunnleggende om hurtigbufring i minne og på disk. Du øver på Android Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Android Academy?

Ingen tidligere erfaring er nødvendig. Android Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Hurtigbufring og ytelse»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Android Academy-leksjonen?

Ja. Alle Android Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Laste inn bilder med Coil
  2. Plassholdere og feiltilstander
  3. Hurtigbufring og ytelse
  4. Spille av lyd og video
← Tilbake til Android Academy