Android + Picasso: changing URL cache expiration

后端 未结 3 1692
情书的邮戳
情书的邮戳 2020-12-03 06:20

I am using Picasso to download and display images in views all accros my application. Those images are changing very rarely (they are considered valid for a few months).

相关标签:
3条回答
  • 2020-12-03 06:39

    Disk caching happens "below" Picasso inside the HTTP client. In fact, this process is completely transparent. We never explicitly ask for a cached-version or an internet-version, the HTTP client will make the decision internally and do the right thing.

    Because we opted to leverage the HTTP client for caching, we're offered very little control over how the caching actually happens. To answer your question, no, there is no way to tell Picasso (or OkHttp) to cache an image for longer than its headers allow.

    0 讨论(0)
  • 2020-12-03 06:48

    I solved it with a Home-made cache, the trick is to add a parameter to the URL that is not used, but making each URL different every X minutes

    Calendar cal2 = Calendar.getInstance();
    long d = cal2.getTimeInMillis();
    int extra =  (int) Math.ceil(d/ (10*60*1000));    // 10 minutes cache
    
    Picasso.with(getBaseContext())
                .load("http://www.myurl.cat/myimage.png&extra=" + extra)
                .placeholder(R.drawable.graphicLoading)
                .error(R.drawable.graphicLoadingError)
                .into(bottomGraphic);
    
    0 讨论(0)
  • 2020-12-03 06:48

    Before thinking about HTTP behavior, make sure you set a large max size for the disk cache:

    cache = Cache(File(application.filesDir, "photos"), Long.MAX_VALUE)
    

    (MAX_VALUE is not recommended for production.) Don't store the cache in application.cacheDir, because android can clear that whenever it wants.

    Add an interceptor to set max-stale, which tells the disk cache to use all old files:

        val httpClient = OkHttpClient.Builder().cache(cache).addInterceptor { chain ->
            // When offline, we always want to show old photos.
            val neverExpireCacheControl = CacheControl.Builder().maxStale(Int.MAX_VALUE, TimeUnit.SECONDS).build()
            val origRequest = chain.request()
            val neverExpireRequest = origRequest.newBuilder().cacheControl(neverExpireCacheControl).build()
    
            chain.proceed(neverExpireRequest)
        }.build()
    
        return Picasso.Builder(application).downloader(OkHttp3Downloader(httpClient)).loggingEnabled(true).build()
    

    I discovered this solution by debugging CacheStrategy.getCandidate(). Take a look there if this doesn't solve your problem.

    0 讨论(0)
提交回复
热议问题