Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 仅当本地缓存的数据早于5分钟时,才进行改装以从服务器获取新数据_Android_Kotlin_Caching_Retrofit - Fatal编程技术网

Android 仅当本地缓存的数据早于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

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

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分钟,后端不能/不可以