Picasso: what it is, image loading and working in Android applications

Author: IT Sectr Published: 2026-05-05 Reading time: 8 min

Picasso is a library for loading images in Android applications, developed by Square. The library provides a simple and expressive API for loading, caching, and displaying graphics from the network. According to Picasso’s GitHub statistics, the library has been downloaded more than 100,000 times. Picasso automatically manages memory and caches images on multiple levels.

Key Takeaways

  • Picasso — an image loading library from Square with a simple API for Android
  • Caching on disk and in memory reduces load time for repeated images
  • Transformations Crop, Resize, and Rotate are applied to images on the fly
  • Placeholder and error images are displayed during loading and on error
  • Loading priorities allow managing the order of image display

What is Picasso?

Picasso is a library for asynchronous image loading in Android, created by Square. It was named after the artist Pablo Picasso, reflecting the library’s philosophy: turning a complex task into a simple and elegant API. It is the most popular library for image loading in the Android community.

Picasso’s architecture is minimalist: the library uses a thread pool for loading, LruCache for in-memory cache, and DiskLruCache for disk cache. Unlike Glide, Picasso does not require AppGlideModule configuration and is ready to use immediately after adding the dependency. This makes it an ideal choice for prototypes and small projects.

Picasso 2.8 is the latest stable version, compatible with Android API 21+ and Java 8+. The library does not require configuration of Gradle plugins or annotations, which simplifies migration between versions and reduces the likelihood of errors during updates. Despite its long history, Picasso remains in demand in thousands of projects worldwide.

The main task of Picasso is to load an image by URL, decode it, resize it if necessary, and display it in an ImageView. The library automatically manages background threads, cache, and ImageView reuse in lists.

Since its release in 2013, Picasso has become the standard for image loading in the Android community. The library is used in thousands of applications thanks to its minimal entry threshold — only one line of code is needed for first use.

Priorities and Request Cancellation

Priorities in Picasso allow managing the loading order of images. By default, all requests have normal priority, but for critical images, a high priority can be set via the priority method. If an ImageView is reused (for example, in RecyclerView), Picasso automatically cancels the previous request and starts a new one, preventing image flickering during scrolling.

Key Features of Picasso

Picasso offers a set of features that cover the main image handling scenarios in mobile applications without unnecessary complexity.

Multi-level Caching

Cache in Picasso consists of two levels: RAM for fast access and disk for permanent storage. When requesting an image, the library first checks the memory cache, then the disk, and only then performs a network request. This significantly speeds up the display of repeatedly loaded images.

Image Transformations

Transformations allow resizing, cropping, or rotating an image without decoding the original each time. Picasso provides built-in transformations CenterCrop and CenterInside, and also allows creating custom ones through the Transformation interface. Transformed images are cached separately.

Placeholder and Error Images

Placeholder is displayed while the image is being loaded from the network, giving the user visual feedback. An error image is shown when loading fails. Picasso also supports an image that is displayed until a new version is loaded, which is useful for updatable avatars.

Loading from Different Sources

Picasso supports loading images from URLs, resources, files, content providers, and URIs. The load() method is overloaded for all these types, and the library automatically determines the source. For resources and files, Picasso does not perform a network request but loads data directly, which speeds up the display of built-in graphics.

How Does Picasso Work?

Picasso uses an architecture based on RequestCreator and Dispatcher. Each request is created through Picasso.get().load() and executed in a thread pool. The Dispatcher manages the request queue, priorities, and cancellation when ImageView is reused.

Request Architecture

When calling into(view), Picasso creates an Action object that contains the URL, transformations, target, and callback. The Action is placed in the Dispatcher queue. The engine loads the image through Downloader (OkHttp by default), decodes the Bitmap, applies transformations, and delivers the result to the UI thread. All images are automatically fitted to the ImageView size.

java
Picasso.get()
    .load("https://example.com/image.jpg")
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .resize(400, 300)
    .centerCrop()
    .into(imageView)

Installing and Configuring Picasso

Installing Picasso is done via Gradle. The library is distributed through Maven Central and does not require complex configuration. The minimum Android API version is 21.

Adding the Dependency

In the module-level build.gradle file, add implementation ‘com.squareup.picasso:picasso:2.8’. After Gradle sync, Picasso is ready to use. For network operations, Picasso automatically uses OkHttp if it is present in the project, or the built-in HttpURLConnection.

groovy
dependencies {
    implementation "com.squareup.picasso:picasso:2.8"
}

// Kafka for loading from OkHttp (optional)
implementation "com.squareup.okhttp3:okhttp:4.12.0"

Debug Indicator and Cache

Debug indicator in Picasso shows a colored triangle in the corner of each image: red for network loading, blue for disk cache, green for memory cache. It is enabled by calling setIndicatorsEnabled(true) on the Picasso instance. The default cache size is 15% of the device’s available memory.

To configure a custom Picasso instance, use Picasso.Builder. It allows setting an Executor for background threads, a Downloader for network requests, MemoryCache, and DiskCache. A custom instance is especially useful in tests, where you can substitute the Downloader with a stub that returns an image without a network request.

Picasso Usage Examples

Examples below demonstrate typical scenarios for working with Picasso: loading a simple image, using transformations, and loading in RecyclerView.

Loading an Image into ImageView

Basic loading into an ImageView is done with a single call. Picasso automatically fits the image to the view’s dimensions taking scaleType into account. A placeholder is shown until loading completes, and an error image is shown when a connection error occurs.

java
Picasso.get()
    .load("https://example.com/photo.jpg")
    .placeholder(R.drawable.loading)
    .error(R.drawable.broken_image)
    .fit()
    .centerCrop()
    .into(imageView)

Applying a Custom Transformation

BlurTransformation blurs the image with a given radius. Custom transformations implement the Transformation interface with the transform method. The cache stores the transformation result under a unique key to avoid reapplying it.

java
public class BlurTransformation implements Transformation {
    @Override
    public Bitmap transform(Bitmap source) {
        Bitmap blurred = Bitmap.createBitmap(source);
        RenderScript rs = RenderScript.create(context);
        // applying blur
        source.recycle();
        return blurred;
    }

    @Override
    public String key() {
        return "blur";
    }
}

Loading Images in RecyclerView

In RecyclerView, Picasso automatically cancels requests for ImageViews that have scrolled off screen and reuses already loaded images. This prevents memory leaks and ensures smooth scrolling.

java
public void onBindViewHolder(ViewHolder holder, int position) {
    String url = items.get(position).getImageUrl();
    Picasso.get()
        .load(url)
        .fit()
        .centerCrop()
        .into(holder.imageView);
}

Picasso vs Glide: Library Comparison

Comparing Picasso and Glide is a common question when choosing an image loading library for Android. Both libraries solve the same task but have different priorities and usage characteristics.

Picasso is better suited for projects where simplicity and minimal APK size are important. Glide is chosen when GIF support, video frames, and maximum memory optimization are needed. Glide automatically scales the image to the exact ImageView size, which reduces memory consumption by up to 50% compared to Picasso in some scenarios.

In performance tests, Glide shows better results when working with RecyclerView thanks to its preloading mechanism and automatic request cancellation during fast scrolling. Picasso uses a simpler strategy, which makes it predictable but less efficient on large data volumes.

Picasso focuses on API simplicity and minimal size. Glide offers broader functionality: support for GIFs, animated images, video frames, and lifecycle integration. Glide also manages memory more efficiently thanks to automatic scaling to ImageView size.

CriterionPicassoGlide
Library Size~120 KB~500 KB
GIF SupportNoYes
Video FramesNoYes
DeveloperSquareGoogle (Bumptech)
APIFluent chainRequestBuilder

According to Android Developer Relations, Glide is recommended by Google as the preferred library for image loading in new projects. Picasso remains an excellent choice for simple projects where GIFs and video frames are not needed.

Frequently Asked Questions

How is Picasso different from Glide?

Picasso is smaller in size and easier to use. Glide supports GIFs and video frames, manages memory more efficiently, and is recommended by Google. The choice depends on the project’s need for additional formats.

How to clear the Picasso cache?

To clear the Picasso cache, use the method Picasso.get().invalidate(url) for a single image or shutdown() for a full clear. The disk cache is deleted when the app is reinstalled or through system settings.

How does Picasso handle screen rotation?

Picasso does not depend on screen rotation. Loaded images are stored in the cache and displayed from it when the Activity is recreated. To speed things up, use ViewModel together with Picasso to preserve loaded data.

Can I use Picasso with Kotlin?

Yes, Picasso is fully compatible with Kotlin. Kotlin developers can use extension functions for a more concise syntax or apply the koptional library for handling null values when loading images.

How does Picasso manage memory?

Picasso uses LruCache for in-memory cache, automatically clearing unused images. The default cache size is 15% of the app’s available memory. When memory is low, Picasso frees resources through onTrimMemory.

Summary

  • Picasso — a lightweight image loading library from Square with a minimal API
  • Caching on disk and in memory with automatic size management
  • Transformations CenterCrop, CenterInside, and custom ones through the Transformation interface
  • Placeholder and error images for a smooth user experience
  • Automatic request cancellation in RecyclerView prevents unnecessary loading
  • Debug indicator helps visually identify the image source
  • Library size is only 120 KB — minimal impact on APK size

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also