android - 仅当本地缓存数据超过 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()
。我不确定他是使用本地缓存还是每次都发送请求。
解决方案
你需要这样的缓存拦截器:
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
:
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();
推荐阅读
- asp.net-mvc - 在 ASP.Net MVC 中更新数据库后,我们可以自动更新模型吗?
- python - 如何从 Matplotlib 谱图中删除图例?
- opencv - 最新版本的opencv是否包含dlib
- android - 应用程序启动器图标未显示在 android 电视的主屏幕中
- java - 以角度将字符串转换为字节[]并将其保存为pdf
- ios - 如何解决与 webView 及其子视图的 Gesture 冲突?
- javascript - 检查数组的值是否存在于不同数组的对象中
- c# - “IServiceCollection”不包含“AddAWSService”的定义,并且在 asp.net core 2.2 中没有可访问的扩展方法“AddAWSService”错误?
- google-cloud-platform - gcp - 在数据库插入时触发云功能?
- vue.js - Axios : 添加 validateStatus 钩子以获取 HTTP 304 响应