Android 仅当本地缓存的数据早于5分钟时,才进行改装以从服务器获取新数据
只有当本地缓存的数据超过5分钟或不存在时,我才必须让改装客户端从服务器获取新数据Android 仅当本地缓存的数据早于5分钟时,才进行改装以从服务器获取新数据,android,kotlin,caching,retrofit,Android,Kotlin,Caching,Retrofit,只有当本地缓存的数据超过5分钟或不存在时,我才必须让改装客户端从服务器获取新数据 private-fun-initreformation(){ val reformation=reformation.Builder() .baseUrl(“https://newsapi.org/") .addConverterFactory(GsonConverterFactory.create()) .build() val service=reformation.create(新闻服务::class.jav
private-fun-initreformation(){
val reformation=reformation.Builder()
.baseUrl(“https://newsapi.org/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service=reformation.create(新闻服务::class.java)
val call=service.getCurrentNews(
“bbc新闻”,
“顶级”,
“75702474c08c4c0c96c4081147233679”
)
排队(对象:Callback{
覆盖fun onResponse(调用:调用,响应:响应){
if(response.issucessful){
val body=response.body()
addDataSet(body!!.articles)
}
}
覆盖失效时的乐趣(调用:调用,t:可丢弃){
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改装(okHttpClient:okHttpClient)=改装.Builder()
.baseUrl(“https://newsapi.org/")
.addConverterFactory(GsonConverterFactory.create())
.客户(okHttpClient)
.build()
私有缓存okHttp(cache:cache):OkHttpClient{
返回OkHttpClient.Builder()
.cache(缓存)
.addNetworkInterceptor(CacheInterceptor())
.build()
}
私有httpCache(应用程序:应用程序):缓存{
返回缓存(application.applicationContext.cacheDir,缓存大小)
}
类缓存拦截器:拦截器{
覆盖趣味拦截(链:Interceptor.chain):okhttp3.Response{
val request=chain.request()
val originalResponse=链。继续(请求)
val shouldUseCache=request.header(CACHE\u CONTROL\u header)!=CACHE\u CONTROL\u NO\u CACHE
如果(!shouldUseCache)返回原始响应
val cacheControl=cacheControl.Builder()
.最大值(5,时间单位:分钟)
.build()
返回originalResponse.newBuilder()
.header(CACHE\u CONTROL\u header,cacheControl.toString())
.build()
}
}
A有了这些,我只需通过以下方式进行改装:
val改装=改装(okHttp(httpCache(应用程序)))
有时工作正常,有时获取数据但仍调用
onFailure()
,似乎调用已排队两次,有时只是抛出onFailure()
。我不确定他是在使用本地缓存还是每次都在发送请求。在您的业务逻辑中,您需要检查您的本地缓存中是否存在数据,或者是否有数据(如果自更新以来已有5分钟)。是否满足标准,以提出改装请求;然后应该发出请求,用数据保存在缓存中的时间戳更新缓存
如果数据在缓存中且少于5分钟,则返回缓存的数据
这是一个很好的入门读物在您的业务逻辑中,您需要检查本地缓存中是否存在数据,或者是否存在自更新后5分钟的数据。是否满足标准,以提出改装请求;然后应该发出请求,用数据保存在缓存中的时间戳更新缓存 如果数据在缓存中且少于5分钟,则返回缓存的数据
这是一个很好的入门读物您需要这样的缓存拦截器:
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();
}
}
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();
将此具有缓存的拦截器添加到您的OkHttpClient
中,如下所示:
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();
}
}
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();
您需要这样的缓存拦截器:
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();
}
}
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();
将此具有缓存的拦截器添加到您的OkHttpClient
中,如下所示:
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();
}
}
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();
我知道,可能是使用改进的缓存模块,或者使用拦截器,但在这里如何实现呢exacly@Amin你知道如何正确地实施吗?我不是100%确定你在寻找什么。如果严格要求精确到5分钟,并且后端无法/没有设置正确的缓存头(即使设置了,也不能期望缓存提供100%的答案保证),那么您有两个选项,添加和侦听器,通过在RAM/DB上存储请求和成功响应来模拟缓存(这有点奇怪)或者尝试在您的存储库中缓存一些响应,这也是不正常的。特别是如果您要缓存大量api调用。我个人认为这一要求存在风险。在很多情况下,您可能会耗尽内存,您的身份验证可能会更改,用户id可能会更改,在很多情况下您都必须清除它们LH,如果你附加你的API接口,告诉我什么API将遵循这个模式,我可以更好地理解你的情况,但是你的问题似乎与普通缓存有点不同(可能是我误解了你的要求)我知道,可能是使用改进的缓存模块,或者使用拦截器,但在这里如何实现呢exacly@Amin你知道如何正确地实现吗?我不是100%确定你在寻找什么。如果有严格的要求精确到5分钟,后端不能/不可以