[Android SDK] Implementing an Image Cache with Picasso

One of the coolest things about Picasso is that you can customize its behavior in a clean and easy way.

One interesting thing that one can find is the image cache.

Before starting, we have to include Picasso. For this example I’m using version 2.5.2. Inside app/build.gradle:

compile 'com.squareup.picasso:picasso:2.5.2'

Now we have to implement our own class implementing Picasso’s Cache interface. It could look like this:

public class CustomCache implements Cache {
  private Context mContext;
  private final File mCacheDir;

public CustomCache(Context mContext) {
  this.mContext = mContext;
  mCacheDir = ((MyApplication)mContext.getApplicationContext()).getPicturesDir();
 }

@Override
public Bitmap get(String key) {
  key = String.format("%s.png", transform(key) );
  File f = new File(mCacheDir, key);
  return getBitmapFromFile(f.getAbsolutePath());
}

@Override
public void set(String key, Bitmap bitmap) {
  key = String.format("%s.png", transform(key) );
  File f = new File(mCacheDir, key);
  saveBitmapToFile(bitmap, f.getAbsolutePath());
}

@Override
public int size() {
  String[] children = mCacheDir.list();
  return children != null ? children.length : 0;
}

@Override
public int maxSize() {
  return 100;
}

@Override
public void clear() {
  String[] children = mCacheDir.list();
  for (int i = 0; i < children.length; i++) {
      new File(mCacheDir, children[i]).delete();
  }
}

@Override
public void clearKeyUri(String keyPrefix) {

}

private String transform(String s) {
   return s.replaceAll("[^A-Za-z0-9]", "");
}
}

where getBitmapFromFile() and saveBitmapToFile() could be your regular implementations. At the end of the post i’ll provide two sample implementations for these methods.

The next step is to use Picasso.Builder() to make our global Picasso instance use the previous Cache implementation.

This could go in our Application class, or MainActivity’s onCreate() method:

File cacheDir = ((MyApplication)ctx.getApplicationContext()).getPicturesDir();
Cache cache = new CustomCache(ctx);
Picasso picasso = new Picasso.Builder(ctx)
 .downloader(new OkHttpDownloader(cacheDir))
 .memoryCache(cache)
 .build();
Picasso.setSingletonInstance(picasso);

From now on, when using your Picasso instance like usually:

Picasso.with(mContext)
        .load(c.getUser().getImageUrl())
        .placeholder(R.drawable.ic_launcher)
        .resize(48,48)
        .into(userThumbnail);

You’ll have all images cached inside your SD card, in the folder specified by your Cache implementation. So simple, huh?

I hope it’s been helpful for you 🙂

// TODO add getBitmapFromFile(), saveBitmapToFile() :-P
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s