Coil — τι είναι, βασικές έννοιες και ImageLoader στο Android

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-05 Χρόνος ανάγνωσης: 9 λεπ

Coil — είναι μια βιβλιοθήκη για φόρτωση εικόνων στο Android, γραμμένη σε Kotlin και βασισμένη σε κορουτίνες. Σύμφωνα με την επίσημη τεκμηρίωση, η βιβλιοθήκη υποστηρίζει Memory Cache, Disk Cache και μετασχηματισμούς με επιτάχυνση υλικού. Coil ξεχωρίζει για το ελάχιστο μέγεθος APK (περίπου 150 KB) και την πλήρη συμβατότητα με το Jetpack Compose.

Κύρια σημεία

  • Coil — βιβλιοθήκη για φόρτωση εικόνων στο Android που χρησιμοποιεί Kotlin Coroutines και Kotlin Serialization.
  • ImageLoader — κεντρικό στοιχείο που διαχειρίζεται αιτήματα, προσωρινή αποθήκευση και μετασχηματισμούς εικόνων.
  • Memory Cache αποθηκεύει αποκωδικοποιημένες εικόνες bitmap στη μνήμη RAM για άμεση πρόσβαση.
  • Disk Cache αποθηκεύει συμπιεσμένα αρχεία στο δίσκο για εργασία εκτός σύνδεσης και μείωση κίνησης.
  • Jetpack Compose — η βιβλιοθήκη υποστηρίζει AsyncImage και SubcomposeAsyncImage για δηλωτικό UI.

Τι είναι το Coil;

Coil (Coroutine Image Loader) — είναι μια βιβλιοθήκη για φόρτωση εικόνων στο Android, γραμμένη εξ ολοκλήρου σε Kotlin και χρησιμοποιώντας κορουτίνες για ασύγχρονη λειτουργία. Παρέχει ένα ενοποιημένο API για φόρτωση εικόνων bitmap από το δίκτυο, πόρους, σύστημα αρχείων και Content Provider, με αυτόματη προσωρινή αποθήκευση σε πολλαπλά επίπεδα.

Σε αντίθεση με τα Glide και Picasso, το Coil χρησιμοποιεί Kotlin Coroutines αντί για αλυσίδες callback, καθιστώντας τον κώδικα πιο γραμμικό και προβλέψιμο. Όλες οι λειτουργίες φόρτωσης και αποκωδικοποίησης εκτελούνται σε νήματα παρασκηνίου μέσω του Dispatchers.IO, και το αποτέλεσμα παραδίδεται στο κύριο νήμα χωρίς ρητή εναλλαγή.

Το Coil υποστηρίζει μετασχηματισμούς (Round, Blur, Grayscale), κινούμενα σχέδια μετάβασης, SVG και GIF, καθώς και προσαρμοσμένο Target για μη τυπική εμφάνιση. Σύμφωνα με το Google I/O 2023, το Coil συνιστάται στα επίσημα σεμινάρια Jetpack Compose μαζί με το Glide.

  • Μέγεθος APK — περίπου 150 KB (έναντι 500 KB στο Glide)
  • Ελάχιστη έκδοση Android — API 21 (Lollipop)
  • Εξάρτηση — Kotlin Coroutines (ενσωματωμένη)

Πώς λειτουργεί το Coil: ImageLoader και ImageRequest

ImageLoader — το κύριο στοιχείο του Coil, υπεύθυνο για την εκτέλεση αιτημάτων φόρτωσης και τη διαχείριση της προσωρινής μνήμης. Κάθε στιγμιότυπο περιέχει αναφορές σε MemoryCache, DiskCache, BitmapPool και μια δεξαμενή κορουτινών. Από προεπιλογή χρησιμοποιείται ένα singleton που δημιουργείται μέσω Coil.imageLoader(context).

ImageRequest

ImageRequest — ένα αντικείμενο που περιγράφει ένα αίτημα φόρτωσης εικόνας: πηγή δεδομένων (URL, URI, πόρος Int), προορισμός ImageView ή Target, μετασχηματισμοί, ρυθμίσεις προσωρινής αποθήκευσης και placeholder. Το ImageRequest δημιουργείται μέσω builder, προσφέροντας ευελιξία και αναγνωσιμότητα.

kotlin
val request = ImageRequest.Builder(context)
    .data("https://example.com/image.jpg")
    .crossfade(true)
    .size(512, 512)
    .transformations(listOf(RoundedCornersTransformation(12f)))
    .memoryCachePolicy(CachePolicy.ENABLED)
    .diskCachePolicy(CachePolicy.ENABLED)
    .target(imageView)
    .build()

Μετά τη δημιουργία, το ImageRequest μεταβιβάζεται στο ImageLoader μέσω enqueue ή execute. Η μέθοδος enqueue εκκινεί μια κορουτίνα και επιστρέφει ένα Disposable, επιτρέποντας την ακύρωση της φόρτωσης κατά την έξοδο από την οθόνη. Η μέθοδος execute είναι μια συνάρτηση suspend που επιστρέφει απευθείας Result.

Ροή εκτέλεσης αιτήματος

Το ImageLoader ελέγχει διαδοχικά το MemoryCache, το DiskCache και μόνο σε περίπτωση αποτυχίας και των δύο εκτελεί ένα αίτημα δικτύου μέσω HttpEngine. Μετά τη φόρτωση, τα bytes αποκωδικοποιούνται σε Bitmap λαμβάνοντας υπόψη το μέγεθος-στόχο, εφαρμόζονται μετασχηματισμοί, το αποτέλεσμα αποθηκεύεται και στις δύο προσωρινές μνήμες και μεταβιβάζεται στο Target.

  • Memory Cache — ελέγχεται πρώτα, κλειδί — URL + παράμετροι
  • Disk Cache — ελέγχεται όταν απουσιάζει από τη μνήμη, κλειδί — MD5 του URL
  • HttpEngine — από προεπιλογή OkHttp, προσαρμόσιμο μέσω στοιχείου

Βασικά στοιχεία του Coil

Το Coil είναι χτισμένο σε αρχιτεκτονική στοιχείων με δυνατότητα αντικατάστασης οποιουδήποτε μέρους μέσω Dependency Injection. Όλα τα στοιχεία καταχωρούνται στο ImageLoaderFactory και μεταβιβάζονται στον κατασκευαστή του ImageLoader μέσω builder.

ImageLoader

ImageLoader — το σημείο εισόδου για όλες τις λειτουργίες φόρτωσης. Κάθε στιγμιότυπο περιέχει μια δεξαμενή κορουτινών, BitmapPool, MemoryCache, DiskCache και μια λίστα αναχαιτιστών. Από προεπιλογή δημιουργείται ένα καθολικό στιγμιότυπο, αλλά για αρθρωτό έλεγχο μπορούν να δημιουργηθούν ξεχωριστά στιγμιότυπα με απομονωμένη προσωρινή μνήμη.

MemoryCache

MemoryCache — προσωρινή μνήμη εντός RAM βασισμένη σε LRU (Least Recently Used) που αποθηκεύει αποκωδικοποιημένα αντικείμενα Bitmap. Το προεπιλεγμένο μέγιστο μέγεθος είναι 25% της διαθέσιμης μνήμης της εφαρμογής, αλλά όχι λιγότερο από 32 MB. Το κλειδί προσωρινής μνήμης σχηματίζεται από URL + μέγεθος + μετασχηματισμούς, αποκλείοντας την παροχή μη ενημερωμένης εικόνας.

DiskCache

DiskCache — προσωρινή μνήμη αρχείων για ακατέργαστα δεδομένα (JPEG, PNG, WebP) και αποκωδικοποιημένα μεταδεδομένα. Βρίσκεται στον κατάλογο προσωρινής μνήμης της εφαρμογής και υποστηρίζει αυτόματο καθαρισμό όταν ξεπεραστεί το όριο. Η εργασία με το δίσκο εκτελείται μέσω DiskCache.Builder με ρύθμιση καταλόγου και μέγιστου μεγέθους.

Επίπεδα προσωρινής αποθήκευσης στο Coil

Coil υλοποιεί μια πολυεπίπεδη στρατηγική προσωρινής αποθήκευσης που ελαχιστοποιεί τα αιτήματα δικτύου και επιταχύνει την εμφάνιση εικόνων. Κάθε επίπεδο έχει το δικό του σκοπό και διάρκεια ζωής δεδομένων.

ΕπίπεδοΤύπος αποθήκευσηςΔιάρκεια ζωήςΠροεπιλεγμένο μέγεθος
Memory CacheBitmap στη μνήμηΜέχρι αντικατάσταση LRU25% heap, από 32 MB
Disk CacheΑρχεία JPEG/WebPΜέχρι υπέρβαση ορίου250 MB
Http CacheΑπαντήσεις OkHttpΣύμφωνα με κεφαλίδες Cache-ControlΕξαρτάται από τον πελάτη HTTP

Το Memory Cache παρέχει άμεση πρόσβαση σε ήδη αποκωδικοποιημένα bitmap. Το Disk Cache εγγυάται τη λειτουργία της εφαρμογής χωρίς δίκτυο (offline-first) μετά την πρώτη φόρτωση. Http Cache στο επίπεδο OkHttp επεξεργάζεται αιτήματα υπό όρους ETag και If-Modified-Since.

Οι πολιτικές προσωρινής αποθήκευσης διαμορφώνονται ανά αίτημα μέσω CachePolicy με τρεις τιμές: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED. Για παράδειγμα, για τα avatar χρηστών μπορεί να οριστεί READ_ONLY για Memory Cache και ENABLED για Disk Cache.

Παραδείγματα χρήσης Coil σε Kotlin

Το Coil προσφέρει διάφορους τρόπους ενσωμάτωσης ανάλογα με την αρχιτεκτονική της εφαρμογής. Ας εξετάσουμε τρία βασικά σενάρια με λειτουργικά παραδείγματα κώδικα.

Φόρτωση σε ImageView μέσω επέκτασης

load — συνάρτηση επέκτασης για ImageView, ο απλούστερος τρόπος φόρτωσης εικόνας σε μία γραμμή. Η συνάρτηση δέχεται URL, URI, πόρο Int ή File και όλες τις προαιρετικές παραμέτρους μέσω ενός ρυθμιστή lambda.

kotlin
imageView.load("https://example.com/photo.jpg") {
    crossfade(true)
    placeholder(R.drawable.placeholder)
    error(R.drawable.error)
    size(300, 300)
    transformations(CircleCropTransformation())
}

Η μέθοδος load επιστρέφει ένα Disposable που μπορεί να ακυρωθεί στο onDestroy ή κατά την επαναχρησιμοποίηση του View. Αυτό αποτρέπει διαρροές μνήμης και περιττά αιτήματα δικτύου κατά τη γρήγορη κύλιση λίστας.

Χρήση σε Jetpack Compose

AsyncImage — συνάρτηση composable για φόρτωση εικόνων σε δηλωτικό UI. Δέχεται οποιαδήποτε πηγή δεδομένων και τρεις προαιρετικές παραμέτρους για καταστάσεις: placeholder, error και success.

kotlin
@Composable
fun NetworkImage(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "εικόνα δικτύου",
        placeholder = ColorPainter(Color.Gray),
        error = ColorPainter(Color.Red)
    )
}

SubcomposeAsyncImage — μια πιο ευέλικτη έκδοση που επιτρέπει την προσαρμογή της εμφάνισης κατά τη φόρτωση μέσω μιας υποδοχής περιεχομένου. Αυτό είναι χρήσιμο για σκελετούς (shimmer) και γραμμές προόδου.

Προσαρμοσμένο Target για μη τυπική έξοδο

Εάν το ImageView ή το AsyncImage δεν είναι κατάλληλα, μπορεί να υλοποιηθεί Target με μία μόνο μέθοδο onSuccess που δέχεται Bitmap. Αυτό χρησιμοποιείται για φόρτωση σε Notification, RemoteViews ή υφή OpenGL.

kotlin
val target = object : BitmapTarget() {
    override fun onSuccess(result: Bitmap) {
        notificationRemoteView.setImageViewBitmap(R.id.icon, result)
    }
}

imageLoader.enqueue(
    ImageRequest.Builder(context)
        .data(url)
        .target(target)
        .build()
)

Σύγκριση Coil με άλλες βιβλιοθήκες

Η επιλογή βιβλιοθήκης για φόρτωση εικόνων εξαρτάται από τις απαιτήσεις του έργου. Coil ανταγωνίζεται τα Glide και Picasso, καθένα από τα οποία έχει τα δυνατά του σημεία. Η σύγκριση των κύριων χαρακτηριστικών παρουσιάζεται στον πίνακα.

ΧαρακτηριστικόCoilGlidePicasso
ΓλώσσαKotlin (100%)Java + KotlinJava
Μέγεθος APK~150 KB~500 KB~120 KB
ΚορουτίνεςΕνσωματωμένεςΌχι (callback)Όχι (callback)
Jetpack ComposeΕγγενής υποστήριξηΜέσω AccompanimentΤρίτου μέρους
GIF/WebPΝαι (ενσωματωμένο)Ναι (ενσωματωμένο)Όχι
Σύσταση GoogleΝαι (I/O 2023)ΝαιΌχι

Για νέα έργα σε Kotlin και Jetpack Compose, το Coil γίνεται η φυσική επιλογή χάρη στη μηδενική πρόσθετη εξάρτηση από κορουτίνες και το ελάχιστο μέγεθος. Το Glide παραμένει προτιμότερο για σύνθετα σενάρια με κινούμενα σχέδια και προεπισκοπήσεις βίντεο. Το Picasso υστερεί και των δύο σε λειτουργικότητα, αλλά κερδίζει σε απλότητα.

Ρύθμιση Coil σε έργο Android

Η σύνδεση του Coil με ένα έργο Android γίνεται μέσω εξάρτησης Gradle. Μετά την προσθήκη, η βιβλιοθήκη καταχωρεί αυτόματα το ImageLoader μέσω ContentProvider, επομένως δεν απαιτείται χειροκίνητη αρχικοποίηση στο Application. Εάν χρειάζεται προσαρμογή, δημιουργείται δικό σας ImageLoader μέσω builder.

kotlin
// build.gradle.kts (μονάδα εφαρμογής)
dependencies {
    implementation("io.coil-kt:coil:2.6.0")
    // Επιπλέον για Jetpack Compose:
    implementation("io.coil-kt:coil-compose:2.6.0")
    // Για υποστήριξη SVG:
    implementation("io.coil-kt:coil-svg:2.6.0")
    // Για υποστήριξη GIF:
    implementation("io.coil-kt:coil-gif:2.6.0")
}

Για την προσαρμογή του ImageLoader χρησιμοποιείται ImageLoaderFactory — ένα singleton που δημιουργείται στο Application.onCreate. Στο εργοστάσιο μπορούν να ρυθμιστούν όρια προσωρινής μνήμης, πελάτης HTTP, προσαρμοσμένοι αποκωδικοποιητές και καταγραφή. Από προεπιλογή το Coil χρησιμοποιεί OkHttp με έτοιμη δεξαμενή συνδέσεων.

kotlin
class App : Application(), ImageLoaderFactory {
    override fun newImageLoader(): ImageLoader {
        return ImageLoader.Builder(this)
            .memoryCache {
                MemoryCache.Builder()
                    .maxSizePercent(0.25)
                    .build()
            }
            .diskCache {
                DiskCache.Builder()
                    .directory(cacheDir.resolve("coil_cache"))
                    .maxSizeBytes(512 * 1024 * 1024)
                    .build()
            }
            .build()
    }
}

Συχνές ερωτήσεις

Τι είναι το Coil και που χρησιμοποιείται;

Coil — βιβλιοθήκη για φόρτωση εικόνων στο Android, γραμμένη σε Kotlin με χρήση κορουτινών. Χρησιμοποιείται για ασύγχρονη φόρτωση, προσωρινή αποθήκευση και εμφάνιση εικόνων bitmap από το δίκτυο, πόρους ή σύστημα αρχείων.

Τι διαφορά έχει το Coil από το Glide;

Το Coil είναι γραμμένο 100% σε Kotlin και χρησιμοποιεί κορουτίνες αντί για τον μηχανισμό callback στο Glide. Το Coil έχει μικρότερο μέγεθος APK (~150 KB έναντι ~500 KB) και εγγενή υποστήριξη για Jetpack Compose μέσω AsyncImage.

Πώς να προσθέσω το Coil σε ένα έργο Kotlin;

Προσθέστε την εξάρτηση io.coil-kt:coil:2.6.0 στο build.gradle.kts. Για Jetpack Compose προσθέστε επίσης io.coil-kt:coil-compose:2.6.0. Η βιβλιοθήκη καταχωρεί αυτόματα το ImageLoader μέσω ContentProvider.

Ποιοι τύποι εικόνων υποστηρίζονται από το Coil;

Coil υποστηρίζει JPEG, PNG, WebP, BMP, SVG (μέσω της μονάδας coil-svg) και GIF (μέσω της μονάδας coil-gif). Οι μορφές AVIF και HEIF υποστηρίζονται μέσω προσαρμοσμένου αποκωδικοποιητή σε συσκευές με Android 10+.

Πώς να ρυθμίσω την προσωρινή μνήμη στο Coil;

Η προσωρινή μνήμη ρυθμίζεται μέσω ImageLoader.Builder: memoryCache με καθορισμό ποσοστού του heap, diskCache με διαδρομή και όριο σε bytes. Οι πολιτικές προσωρινής μνήμης (ENABLED, DISABLED, READ_ONLY) ρυθμίζονται ανά αίτημα μέσω CachePolicy.

Σύνοψη

  • Coil — βιβλιοθήκη φόρτωσης εικόνων σε Kotlin με πλήρη υποστήριξη για κορουτίνες και Jetpack Compose.
  • ImageLoader διαχειρίζεται αιτήματα, προσωρινή αποθήκευση και μετασχηματισμούς, χρησιμοποιώντας δύο επίπεδα προσωρινής μνήμης: Memory Cache και Disk Cache.
  • AsyncImage και SubcomposeAsyncImage παρέχουν ενσωμάτωση με Compose, υποστηρίζοντας καταστάσεις placeholder, error και success.
  • Μέγεθος APK ~150 KB καθιστά το Coil μία από τις πιο συμπαγείς βιβλιοθήκες φόρτωσης εικόνων στην αγορά.
  • Μετασχηματισμοί (RoundedCorners, CircleCrop, Blur) είναι ενσωματωμένοι στη βιβλιοθήκη και λειτουργούν με επιτάχυνση υλικού.
  • Disk Cache παρέχει πρόσβαση εκτός σύνδεσης σε προηγουμένως φορτωμένες εικόνες με ρυθμιζόμενο όριο αποθήκευσης.
  • Coil συνιστάται από την Google στους επίσημους οδηγούς Jetpack Compose, επιβεβαιώνοντας την κατάστασή του ως σύγχρονο πρότυπο.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης