仅当本地缓存的数据早于5分钟时,才进行翻新以从服务器获取新数据 [英] Make retrofit fetch new data from server only if localy cached data is older than 5 minutes

查看:56
本文介绍了仅当本地缓存的数据早于5分钟时,才进行翻新以从服务器获取新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to make my retrofit client fetch new data from the server only if the locally cached data is older than 5 minutes or if it doesn't exist

    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和拦截器,但是我不确定应该怎么做.

It is shown above how I am currently using a retrofit. I've used okhttpclient and interceptors before, but I'm not sure how exactly I should do it.

我现在已经弥补了这一点,但是它不能正常工作.

I made up with this now, but it's not working as it shoud.

    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)))有时工作正常,有时获取数据,但仍然调用 onFailure(),似乎调用已排队两次,有时只是抛出了 onFailure().我不确定他是使用本地缓存还是每次发送请求.

A with all this, I just build retrofit with: val retrofit = retrofit(okHttp(httpCache(application ))) Sometimes it works fine, sometimes gets data but still call onFailure(), it seems that call was enqueued twice, and sometimes just throw onFailure(). I'm am not sure if he is using local cache or is he sending requests every time.

推荐答案

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

You need cache interceptor like this:

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();
    }
}

将此拦截器和 Cache 添加到您的 OkHttpClient 中,如下所示:

Add this interceptor with Cache to your OkHttpClient like this:

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();

这篇关于仅当本地缓存的数据早于5分钟时,才进行翻新以从服务器获取新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆