J'utilise la modification 2 et OkHttp3 pour demander des données du serveur. Je viens d'ajouter un code de cache hors connexion mais cela ne fonctionne pas comme prévu. J'ai l'erreur "Impossible de résoudre l'hôte" <> ": Aucune adresse associée au nom d'hôte."
Cela se produit lorsque vous essayez d'extraire les données du cache (sans connexion Internet). Un extrait de code est ci-dessous.
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
public static Interceptor provideOfflineCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!hasNetwork) {
CacheControl cacheControl = new CacheControl.Builder()
.onlyIfCached()
.maxStale(7, TimeUnit.DAYS)
.build();
request = request.newBuilder()
.removeHeader("Pragma")
.cacheControl(cacheControl)
.build();
}
return chain.proceed(request);
}
};
}
private static Cache provideCache() {
Cache cache = null;
try {
cache = new Cache(new File(AdeptAndroid.getInstance().getCacheDir(), "http-cache"),
10 * 1024 * 1024); // 10 MB
} catch (Exception e) {
Log.d("Test", "Could not create Cache!");
}
return cache;
}
Et enfin, une méthode combinant tous ces éléments est disponible.
private static OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(provideHttpLoggingInterceptor())
.addInterceptor(provideOfflineCacheInterceptor())
.addNetworkInterceptor(provideCacheInterceptor())
.cache(provideCache())
.build();
}
Votre réponse de serveur a un en-tête "Pragma: no-cache". Vous devez supprimer cet en-tête dans votre intercepteur de réponse et non pas votre intercepteur de requête.
Dans votre code actuel, vous l'avez supprimé de l'intercepteur de demandes.
Votre provideCacheInterceptor()
devrait ressembler à ceci:
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.removeHeader("Pragma")
.build();
}
};
}
Vérifiez que votre réseau est "activé" en mode autorisation du fichier manifeste. Mode avion désactivé sur l'émulateur.
J'ai eu la même erreur dans mon projet avec kotlin, et je l'ai corrigé comme ceci:
client.addInterceptor(provideOfflineCacheInterceptor(context))
client.addNetworkInterceptor(provideCacheInterceptor(context))
private fun provideOfflineCacheInterceptor(context: Context): Interceptor {
return Interceptor { chain ->
var request = chain.request()
var cacheHeaderValue = if (!hasNetwork(context)!!){
"public, only-if-cached, max-stale=" + 60 * 60 * 24 * 1
} else {
"public, max-age=" + 5
}
request = request.newBuilder().header("Cache-Control", cacheHeaderValue).build()
chain.proceed(request)
}
}
private fun provideCacheInterceptor(context: Context): Interceptor {
return Interceptor { chain ->
val request = chain.request()
var cacheHeaderValue = if (!hasNetwork(context)!!){
"public, only-if-cached, max-stale=" + 60 * 60 * 24 * 1
} else {
"public, max-age=" + 5
}
//request = request.newBuilder().build()
val response = chain.proceed(request)
response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", cacheHeaderValue)
.build()
}
}