How do I use disk caching in Picasso? How do I use disk caching in Picasso? android android

How do I use disk caching in Picasso?


This is what I did. Works well.

First add the OkHttp to the gradle build file of the app module:

compile 'com.squareup.picasso:picasso:2.5.2'compile 'com.squareup.okhttp3:okhttp:3.10.0'compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'

Then make a class extending Application

import android.app.Application;import com.jakewharton.picasso.OkHttp3Downloader;import com.squareup.picasso.Picasso;public class Global extends Application {    @Override    public void onCreate() {        super.onCreate();        Picasso.Builder builder = new Picasso.Builder(this);        builder.downloader(new OkHttp3Downloader(this,Integer.MAX_VALUE));        Picasso built = builder.build();        built.setIndicatorsEnabled(true);        built.setLoggingEnabled(true);        Picasso.setSingletonInstance(built);    }}

add it to the Manifest file as follows :

<application        android:name=".Global"        .. ></application>

Now use Picasso as you normally would. No changes.

EDIT:

if you want to use cached images only. Call the library like this. I've noticed that if we don't add the networkPolicy, images won't show up in an fully offline start even if they are cached. The code below solves the problem.

Picasso.with(this)            .load(url)            .networkPolicy(NetworkPolicy.OFFLINE)            .into(imageView);

EDIT #2

the problem with the above code is that if you clear cache, Picasso will keep looking for it offline in cache and fail, the following code example looks at the local cache, if not found offline, it goes online and replenishes the cache.

Picasso.with(getActivity()).load(imageUrl).networkPolicy(NetworkPolicy.OFFLINE).into(imageView, new Callback() {    @Override    public void onSuccess() {    }    @Override    public void onError() {        //Try again online if cache failed        Picasso.with(getActivity())                .load(posts.get(position).getImageUrl())                .error(R.drawable.header)                .into(imageView, new Callback() {            @Override            public void onSuccess() {            }            @Override            public void onError() {                Log.v("Picasso","Could not fetch image");            }        });    }});


1) answer of first question : according to Picasso Doc for With() method

The global default Picasso instance returned from with() 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.

But Disk Cache operation for global Default Picasso is only available on API 14+

2) answer of second Question : Picasso use the HTTP client request to Disk Cache operation So you can make your own http request header has property Cache-Control with max-ageAnd create your own Static Picasso Instance instead of default Picasso By using

1] HttpResponseCache (Note: Works only for API 13+ )
2] OkHttpClient (Works for all APIs)

Example for using OkHttpClient to create your own Static Picasso class:

  • First create a new class to get your own singleton picasso object

    import android.content.Context;import com.squareup.picasso.Downloader;import com.squareup.picasso.OkHttpDownloader;import com.squareup.picasso.Picasso;public class PicassoCache {    /**     * Static Picasso Instance     */    private static Picasso picassoInstance = null;    /**     * PicassoCache Constructor     *     * @param context application Context     */    private PicassoCache (Context context) {        Downloader downloader   = new OkHttpDownloader(context, Integer.MAX_VALUE);        Picasso.Builder builder = new Picasso.Builder(context);            builder.downloader(downloader);        picassoInstance = builder.build();    }    /**     * Get Singleton Picasso Instance     *     * @param context application Context     * @return Picasso instance     */    public static Picasso getPicassoInstance (Context context) {        if (picassoInstance == null) {            new PicassoCache(context);            return picassoInstance;        }        return picassoInstance;    }} 
  • use your own singleton picasso object Instead of Picasso.With()

PicassoCache.getPicassoInstance(getContext()).load(imagePath).into(imageView)

3) answer for third question : you do not need any disk permissions for disk Cache operations

References: Github issue about disk cache, two Questions has been answered by @jake-wharton -> Question1 and Question2


For caching, I would use OkHttp interceptors to gain control over caching policy. Check out this sample that's included in the OkHttp library.

RewriteResponseCacheControl.java

Here's how I'd use it with Picasso -

OkHttpClient okHttpClient = new OkHttpClient();    okHttpClient.networkInterceptors().add(new Interceptor() {        @Override        public Response intercept(Chain chain) throws IOException {            Response originalResponse = chain.proceed(chain.request());            return originalResponse.newBuilder().header("Cache-Control", "max-age=" + (60 * 60 * 24 * 365)).build();        }    });    okHttpClient.setCache(new Cache(mainActivity.getCacheDir(), Integer.MAX_VALUE));    OkHttpDownloader okHttpDownloader = new OkHttpDownloader(okHttpClient);    Picasso picasso = new Picasso.Builder(mainActivity).downloader(okHttpDownloader).build();    picasso.load(imageURL).into(viewHolder.image);