首页 > 解决方案 > 仅当本地缓存数据超过 5 分钟时,才使改造从服务器获取新数据

问题描述

仅当本地缓存的数据超过 5 分钟或不存在时,我才必须让我的改造客户端从服务器获取新数据

    private fun initRetrofit(){

        val retrofit = Retrofit.Builder()
            .baseUrl("https://newsapi.org/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service = retrofit.create(NewsService::class.java)
        val call = service.getCurrentNews(
            "bbc-news",
            "top",
            "75702474c08c4c0c96c4081147233679"
        )

        call.enqueue(object : Callback<NewsResponse> {
            override fun onResponse(call: Call<NewsResponse>, response: Response<NewsResponse>) {
                if (response.isSuccessful){
                    val body = response.body()
                    addDataSet(body!!.articles)
                }
            }

            override fun onFailure(call: Call<NewsResponse>, t: Throwable) {
                val alertDialogBuilder = AlertDialog.Builder(this@MainActivity)
                alertDialogBuilder.setTitle("Greška")
                alertDialogBuilder.setMessage("Ups, došlo je do pogreške.")
                alertDialogBuilder.setPositiveButton("U REDU"){ _, _ -> }
                alertDialogBuilder.setCancelable(false)
                alertDialogBuilder.show()

            }
        } )
    }

上面显示了我目前如何使用改造。我以前使用过 okhttpclient 和拦截器,但我不确定我应该怎么做。

我现在解决了这个问题,但它没有按预期工作。

    private fun retrofit(okHttpClient: OkHttpClient) = Retrofit.Builder()
            .baseUrl("https://newsapi.org/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()

    private fun okHttp(cache: Cache): OkHttpClient {
        return OkHttpClient.Builder()
                .cache(cache)
                .addNetworkInterceptor(CacheInterceptor())
                .build()
    }

    private fun httpCache(application: Application): Cache {
        return Cache(application.applicationContext.cacheDir, CACHE_SIZE)
    }

    class CacheInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
            val request = chain.request()
            val originalResponse = chain.proceed(request)

            val shouldUseCache = request.header(CACHE_CONTROL_HEADER) != CACHE_CONTROL_NO_CACHE
            if(!shouldUseCache) return originalResponse

            val cacheControl = CacheControl.Builder()
                    .maxAge(5, TimeUnit.MINUTES)
                    .build()

            return originalResponse.newBuilder()
                    .header(CACHE_CONTROL_HEADER, cacheControl.toString())
                    .build()
        }

    }

有了这一切,我只是构建改造: val retrofit = retrofit(okHttp(httpCache(application ))) 有时它工作正常,有时获取数据但仍然 call onFailure(),似乎 call 被排队两次,有时只是 throw onFailure()。我不确定他是使用本地缓存还是每次都发送请求。

标签: androidkotlincachingretrofit

解决方案


你需要这样的缓存拦截器:

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(5, TimeUnit.MINUTES) // 5 minutes cache
                .build();

        return response.newBuilder()
                .removeHeader("Pragma")
                .removeHeader("Cache-Control")
                .header("Cache-Control", cacheControl.toString())
                .build();
    }
}

像这样添加这个拦截CacheOkHttpClient

File httpCacheDirectory = new File(applicationContext.getCacheDir(), "http-cache");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addNetworkInterceptor(new CacheInterceptor())
            .cache(cache)
            .build();

推荐阅读