Picasso — Influencing Image Caching

We've mentioned at the beginning of this series that Picasso uses a memory and disk cache to load previously requested image much faster. In this blog post, we'll take a much closer look at the caching configuration and how you can adapt the standard behavior.

Picasso Series Overview

Standard Behavior

The default Picasso instance has the following settings (JavaDocs):

This instance is automatically initialized with defaults that are suitable to most implementations.

  • LRU memory cache of 15% the available application RAM
  • Disk cache of 2% storage space up to 50MB but no less than 5MB. (Note: this is only available on API 14+ or if you are using a standalone library that provides a disk cache on all API levels like OkHttp)
  • Three download threads for disk and network access.

It's possible to change the cache sizes, but that goes beyond the scope of this blog post. Going back towards the topic of image caching: Picasso will always try to load the image from the memory cache first. If the image was not requested recently, and consequently the image is not in memory cache, Picasso will check the disk cache next. If it's not available on disk, only then Picasso will start the network request.

Additionally, all requested images are stored in both caches (until they have to be deleted in order to free space). In conclusion, Picasso will check memory -> disk -> network.

In case you want or need Picasso to behave differently, you can customize the memory and network policies. Let's look at the MemoryPolicy.

Memory Policy

Once again, Picasso attempts to get the requested image from the memory first. In case you would like Picasso to skip this step, you can call memoryPolicy(MemoryPolicy policy, MemoryPolicy... additional) on your Picasso request creator. MemoryPolicy is a simple enum with two values: NO_CACHE and NO_STORE.

As an example, a Picasso request for an image which should not be served from memory would use NO_CACHE and look like this:

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[1])
    .memoryPolicy(MemoryPolicy.NO_CACHE)
    .into(imageViewFromDisk);

If you're wondering what the NO_STORE enum can be used for: if you're requesting an image of which you know you'll need it only one single time, call .memoryPolicy(MemoryPolicy.NO_STORE). Consequently, Picasso will not put this image in the memory cache (and thus not kick another important cached image out).

Of course, you can combine these options in a single call:

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[1])
    .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
    .into(imageViewFromDisk);

Beware, calling .memoryPolicy(MemoryPolicy.NO_CACHE) will not prevent Picasso from serving the image from the disk cache! In order to skip both caches, you'll need to take a look at NetworkPolicy.

Network Policy

The way MemoryPolicy regulates the memory cache is identical to the way NetworkPolicy regulates the disk cache. The enums are even named the same way!

If you want to skip the disk cache, call .networkPolicy(NetworkPolicy policy, NetworkPolicy... additional) with NetworkPolicy.NO_CACHE as parameter:

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[2])
    .networkPolicy(NetworkPolicy.NO_CACHE)
    .into(imageViewFromNetwork);

Of course, you can combine the previous options to any possible configuration:

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[2])
    .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
    .networkPolicy(NetworkPolicy.NO_CACHE)
    .into(imageViewFromNetwork); 

Lastly, there is a third neat option for the NetworkPolicy: OFFLINE. If you pass this as parameter, Picasso will try to serve the image from one of the caches, but not make a network request, even if a internet connection is available and the image was not found in the caches.

Outlook

In this blog post, we've looked at the two different kind of caches and how to influence their behavior. If your app uses images a lot, it matters a lot if the images are stored in the correct caches.

In many cases, Picasso's default behavior will serve you very well. However, if you need to adjust things, analyzing and logging the loading behavior would be very helpful. Of course, Picasso fulfills this need. We'll take a closer look into the Picasso debugging options next week.

Explore the Library

Find interesting tutorials and solutions for your problems.