使用 Retrofit、okhttp 和 picasso 缓存图像和字符串
Posted
技术标签:
【中文标题】使用 Retrofit、okhttp 和 picasso 缓存图像和字符串【英文标题】:Caching Images and strings using Retrofit, okhttp and picasso 【发布时间】:2021-04-30 16:37:40 【问题描述】:我正在尝试优化此代码以用于缓存目的。此代码仅在 1 天后重新连接到 Internet 以创建新缓存之前的缓存。我想在它再次访问网络之前让它保持 60 天 make new cache 。使用毕加索从缓存中获取的图像也会变慢 毕加索:2.5.2 改造2:改造:2.7.2 改造2:转换器-gson:2.7.2 okhttp3:okhttp:4.4.1 okhttp3:logging-interceptor:4.4.1
if (retrofit==null)
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.addInterceptor( provideHttpLoggingInterceptor() )
.addInterceptor( provideOfflineCacheInterceptor() )
.addNetworkInterceptor( provideCacheInterceptor() )
.cache( provideCache() )
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
OkHttp3Downloader okHttp3Downloader = new OkHttp3Downloader(okHttpClient);
Picasso picasso = new Picasso.Builder(MyApplication.getInstance())
.downloader(okHttp3Downloader)
.build();
Picasso.setSingletonInstance(picasso);
retrofit = new Retrofit.Builder()
.baseUrl(Global.API_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
private static Cache provideCache ()
Cache cache = null;
try
cache = new Cache( new File(MyApplication.getInstance().getCacheDir(), "wallpaper-cache" ),
100 * 1024 * 1024 ); // 100 MB
catch (Exception e)
Timber.e( e, "Could not create Cache!" );
return cache;
private static HttpLoggingInterceptor provideHttpLoggingInterceptor ()
HttpLoggingInterceptor httpLoggingInterceptor =
new HttpLoggingInterceptor( new HttpLoggingInterceptor.Logger()
@Override
public void log (String message)
Timber.d( message );
Log.v("MYAPI",message);
);
httpLoggingInterceptor.setLevel( BuildConfig.DEBUG ? HEADERS : NONE );
return httpLoggingInterceptor;
public static Interceptor provideCacheInterceptor ()
return new Interceptor()
@Override
public Response intercept (Chain chain) throws IOException
Response response = chain.proceed( chain.request() );
int maxAge = 60 * 60; // read from cache
return response.newBuilder()
.header( CACHE_CONTROL, "public, max-age=" + maxAge)
.removeHeader("Pragma")
.build();
;
public static Interceptor provideOfflineCacheInterceptor ()
return new Interceptor()
@Override
public Response intercept (Chain chain) throws IOException
Request request = chain.request();
if ( !MyApplication.hasNetwork() )
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
request = request.newBuilder()
.header( CACHE_CONTROL, "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
return chain.proceed( request );
;
```
【问题讨论】:
【参考方案1】:你可以像这个例子How to cache okHTTP response from Web server那样在拦截器中重写缓存头
public class CacheInterceptor implements Interceptor
@Override
public Response intercept(Chain chain) throws IOException
Response response = chain.proceed(chain.request());
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(15, TimeUnit.MINUTES) // 15 minutes cache
.build();
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", cacheControl.toString())
.build();
【讨论】:
你能用完整的代码更新我吗,因为我不知道我是否会更改缓存拦截器或离线缓存拦截器或 HttpLoggingInterceptor 请提供一个可运行的复制品,我可以在 Intellij 中将其作为项目打开。也许作为一个github项目,我会看看。以上是关于使用 Retrofit、okhttp 和 picasso 缓存图像和字符串的主要内容,如果未能解决你的问题,请参考以下文章
Okhttp + Retrofit @Body 请求 - 传输编码:添加了分块
OkHttp 和 Retrofit 无限 Post 请求在后台