使用OkHttp拦截器和Retrofit进行缓存

Posted 小陈乱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用OkHttp拦截器和Retrofit进行缓存相关的知识,希望对你有一定的参考价值。

在这篇博客中,我们将学习如何使用 OkHttp 拦截器和 Retrofit 在 android 中缓存 HTTP 响应,以构建离线优先的 Android 应用程序。

让我们了解缓存将如何在我们的 Android 应用程序中帮助我们。

  • 当我们进行网络调用以从服务器获取数据时。
  • 第一次,它将从服务器获取数据,并将 HTTP 响应缓存在客户端。
  • 然后,如果我们再次调用相同的 API,它会立即从缓存中返回数据。

这样,我们的 Android 应用程序可以做两件非常重要的事情:

  • 即使没有互联网连接也能工作。这将有助于我们构建离线优先的应用程序。
  • 由于响应在本地缓存,因此工作速度更快。

现在,让我们学习如何在 OkHttp 和 Retrofit 中启用缓存。在此之前,我们需要了解 Retrofit 使用 OkHttp 客户端进行 HTTP 操作,这意味着无论我们要启用缓存做什么,都需要使用 OkHttp。我们不需要为 Retrofit 做任何额外的事情,因为它将使用我们配置的 OkHttp 客户端。

当我们已经Cache-Control从服务器启用了标头时,事情变得更容易了,然后 OkHttp 将尊重该标头并缓存从服务器发送的特定时间的响应。

但是如果Cache-Control没有从服务器启用呢?我们仍然可以使用拦截器缓存来自 OkHttp 客户端的响应。我们将学习如何。

为此,我们需要实现Interceptor如下:

class CacheInterceptor : Interceptor 
    override fun intercept(chain: Interceptor.Chain): Response 
        val response: Response = chain.proceed(chain.request())
        val cacheControl = CacheControl.Builder()
            .maxAge(10, TimeUnit.DAYS)
            .build()
        return response.newBuilder()
            .header("Cache-Control", cacheControl.toString())
            .build()
    

在这里,我们CacheInterceptor通过实现创建,Interceptor并且我们有一个CacheControl构建器,用于为Cache-Control.

然后,我们需要将其添加CacheInterceptor到OkHttpClientusing 中addNetworkInterceptor。

val okHttpClient = OkHttpClient().newBuilder() 
.addNetworkInterceptor(CacheInterceptor())
.build();

之后,我们可以okHttpClient直接使用它或与 Retrofit 一起使用。

但是,在构建离线优先应用程序时,我们需要了解一个问题。

OkHttp 的设计方式是仅在 Internet 可用时才返回缓存的响应。

  • 它仅在 Internet 可用且数据已缓存时才从缓存中返回数据。
  • 即使数据被缓存但 Internet 不可用,它也会返回错误“没有 Internet 可用”。

如何解决这个问题?

ForceCacheInterceptor除了上面的一个之外,我们还可以创建一个( CacheInterceptor,仅当Cache-Control未从服务器启用标头时)。

class ForceCacheInterceptor : Interceptor 
    override fun intercept(chain: Interceptor.Chain): Response 
        val builder: Request.Builder = chain.request().newBuilder()
        if (!IsInternetAvailable()) 
            builder.cacheControl(CacheControl.FORCE_CACHE);
        
        return chain.proceed(builder.build());
    

然后,OkHttpClient像下面这样添加拦截器:

val okHttpClient = OkHttpClient().newBuilder()
.addNetworkInterceptor(CacheInterceptor()) // only if Cache-Control header is not enabled from the server
.addInterceptor(ForceCacheInterceptor())
.build();

在这里,我们需要注意我们正在添加ForceCacheInterceptorusingOkHttpClient和addInterceptor()not addNetworkInterceptor()。

  • addInterceptor:用于在应用程序级别添加拦截器。
  • addNetworkInterceptor:顾名思义,用于在网络级别添加拦截器。
    之后,我们可以okHttpClient直接使用它或与 Retrofit 一起使用,它会按预期工作。

这就是我们如何使用 OkHttp Interceptor 和 Retrofit 在 Android 中缓存 HTTP 响应以构建离线优先的 Android 应用程序。

现在就是这样。

以上是关于使用OkHttp拦截器和Retrofit进行缓存的主要内容,如果未能解决你的问题,请参考以下文章

Retrofit全攻略——进阶篇

Retrofit2缓存实现

改造 OKHTTP 离线缓存不起作用

java 使用Retrofit 1.9 + OkHttp 2.2进行Android响应缓存

Retrofit2.0+OkHttp打印Request URL(请求地址参数)

Retrofit2.0+OkHttp打印Request URL(请求地址参数)