使用Retrofit缓存数据

2018-09-10  本文已影响141人  小菜鸟程序媛

原文地址:https://medium.com/mindorks/caching-with-retrofit-store-responses-offline-71439ed32fda
当你使用Retrofit的时候,构建Retrofit实例:

val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()

上面的实例使用的是默认的OkHttpClient作为客户端来执行请求。但是缓存不友好。
接下来我们将创建一个启用缓存的OkHttpClient实例,并且可以处理有效的数据获取。

创建缓存友好的OkHttpClient

  1. 定义一个方法用来检查网络连接情况
fun hasNetwork(context: Context): Boolean? {
  var isConnected: Boolean? = false
  var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
  if(activeNetwork != null && activeNetwork.isConnected)
    isConnectd = true
  return isConnected
}
  1. 定义缓存大小
val cacheSize = (5 * 1024 * 1024).toLong()
  1. 创建缓存变量
val myCache = Cache(context.cacheDir, cacheSize)
  1. 使用拦截器创建OkHttpClient实例
val okHttpClient = OkHttpClient.Builder()
                // Specify the cache we created earlier.
                .cache(myCache)
                // Add an Interceptor to the OkHttpClient.
                .addInterceptor { chain ->
                                 
                    // Get the request from the chain.
                    var request = chain.request()
                                 
                    /* 
                    *  Leveraging the advantage of using Kotlin,
                    *  we initialize the request and change its header depending on whether 
                    *  the device is connected to Internet or not.
                    */ 
                    request = if (hasNetwork(context)!!)
                        /* 
                        *  If there is Internet, get the cache that was stored 5 seconds ago.
                        *  If the cache is older than 5 seconds, then discard it,
                        *  and indicate an error in fetching the response.
                        *  The 'max-age' attribute is responsible for this behavior.
                        */
                        request.newBuilder().header("Cache-Control", "public, max-age=" + 5).build()
                    else
                        /*
                        *  If there is no Internet, get the cache that was stored 7 days ago.
                        *  If the cache is older than 7 days, then discard it,
                        *  and indicate an error in fetching the response.
                        *  The 'max-stale' attribute is responsible for this behavior.
                        *  The 'only-if-cached' attribute indicates to not retrieve new data; fetch the cache only instead.
                        */
                        request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build()
                   // End of if-else statement

                   // Add the modified request to the chain.            
                   chain.proceed(request)
                }
                .build()

将他们都结合到一起

val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                // Adding our OkHttpClient
                .client(okHttpClient)
                .build()

下面就是最终的代码:

val cacheSize = (5 x 1024 x 1024).toLong()
val myCache = Cache(context.cacheDir, cacheSize)

val okHttpClient = OkHttpClient.Builder()
                .cache(myCache)
                .addInterceptor { chain ->
                    var request = chain.request()
                    request = if (hasNetwork(context)!!)
                        request.newBuilder().header("Cache-Control", "public, max-age=" + 5).build()
                    else
                        request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build()
                    chain.proceed(request)
                }
                .build()

val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build()
上一篇 下一篇

猜你喜欢

热点阅读