Interview QuestionPractical QuestionFollow-up Questions

Loading Images from the Network in Jetpack Compose

skydovesJaewoong Eum (skydoves)||7 min read

Loading Images from the Network in Jetpack Compose

Jetpack Compose does not include a built in API for loading images from network URLs. This is by design, because network image loading involves complex concerns such as HTTP fetching, bitmap decoding, memory and disk caching, downsampling, and lifecycle management. Third party libraries handle these concerns with well tested, optimized implementations. The three primary options for Compose are Coil, Glide, and Landscapist, each with different strengths and integration approaches. By the end of this lesson, you will be able to:

  • Explain why Compose does not include built in network image loading.
  • Compare Coil, Glide, and Landscapist in terms of integration and feature sets.
  • Use AsyncImage from Coil for straightforward network image loading.
  • Apply placeholder and error handling strategies for network image components.

Why Built In Support Is Not Provided

Loading images from the network requires downloading data over HTTP, decoding bitmaps at appropriate sizes for the target view dimensions, caching decoded bitmaps in memory and on disk, handling concurrent requests without blocking the main thread, and releasing resources when the image is no longer displayed. Each of these concerns has multiple implementation strategies with different performance tradeoffs. Rather than bundling a single approach into the framework, Compose delegates this to libraries that can evolve independently.

Coil

Coil is a Kotlin first image loading library that integrates natively with Jetpack Compose and Kotlin Multiplatform. It uses Kotlin Coroutines for asynchronous loading and OkHttp for network requests, both of which are commonly already present in Android projects, keeping the incremental dependency size small.

AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = "Profile photo",
    modifier = Modifier.size(120.dp),
    placeholder = painterResource(R.drawable.placeholder),
    error = painterResource(R.drawable.error)
)

AsyncImage handles the full lifecycle: it starts loading when the composable enters the composition, displays a placeholder while loading, shows the result on success, and displays an error drawable on failure. It cancels the request when the composable leaves the composition.

Coil provides ImageRequest for advanced configuration including transformations, cache policies, and custom headers:

This interview continues for subscribers

Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.

Become a Sponsor