Façon correcte de configurer le cache pour OkHttp dans Android
Je suis en train de configurer le cache pour OkHttp, de sorte qu'il ne demande au serveur la première fois que j'essaie de récupérer une réponse du serveur jusqu'à ce que l'en-tête expires date, ou en-tête cache-control qui vient du serveur invalide la réponse à partir du cache.
Actuellement, sa mise en cache de la réponse, mais ne pas l'utiliser lors de la demande de la ressource. Peut-être que c'est pas la façon dont il était censé être utilisé.
Je suis la mise en place OkHttpClient avec cache comme ceci:
public static Cache createHttpClientCache(Context context) {
try {
File cacheDir = context.getDir("service_api_cache", Context.MODE_PRIVATE);
return new Cache(cacheDir, HTTP_CACHE_SIZE);
} catch (IOException e) {
Log.e(TAG, "Couldn't create http cache because of IO problem.", e);
return null;
}
}
Ce est utilisé comme ceci:
if(cache == null) {
cache = createHttpClientCache(context);
}
sClient.setCache(cache);
C'est comment je fais une demande au serveur avec OkHttp que du fait de la non-utilisation du cache:
public static JSONObject getApi(Context context)
throws IOException, JSONException, InvalidCookie {
HttpCookie sessionCookie = getServerSession(context);
if(sessionCookie == null){
throw new InvalidCookie();
}
String cookieStr = sessionCookie.getName()+"="+sessionCookie.getValue();
Request request = new Request.Builder()
.url(sServiceRootUrl + "/api/"+API_VERSION)
.header("Accept", "application/json")
.header("Cookie", cookieStr)
.build();
Response response = sClient.newCall(request).execute();
if(response.code() == 200){
String charset = getResponseCharset(response);
if(charset == null){
charset = "utf-8";
}
String responseStr = new String(response.body().bytes(), charset);
response.body().close();
return new JSONObject(responseStr);
} else if(response.code() == 401){
throw new InvalidCookie();
} else {
return null;
}
}
Si je peux le répertoire que j'ai précisé à la cache pour OkHttp je peux voir le fichier journal et 4 autres fichiers qui contient les réponses à certaines des demandes. Cette demande (le /api j'ai juste collé le code) est stocké sur le répertoire de cache, donc c'était vraiment mis en cache, mais le nom a une .tmp à la fin, comme si il n'a pas été correctement enregistré dans le fichier final, à l'instar de toute autre demande que j'ai faite.
C'est à quoi il ressemble, comme les en-têtes de la réponse du serveur pour la requête:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Expires: Sat, 09 Aug 2014 19:36:08 GMT
Cache-Control: max-age=86400, must-revalidate
Last-Modified: Sun, 04 Aug 2013 15:56:04 GMT
Content-Length: 281
Date: Fri, 08 Aug 2014 19:36:08 GMT
Et c'est de cette façon OkHttp le stocke dans le cache:
{HOST}/api/0.3
GET
0
HTTP/1.1 200 OK
9
Server: Apache-Coyote/1.1
Expires: Sat, 09 Aug 2014 19:36:08 GMT
Cache-Control: max-age=86400, must-revalidate
Last-Modified: Sun, 04 Aug 2013 15:56:04 GMT
Content-Length: 281
Date: Fri, 08 Aug 2014 19:36:08 GMT
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1407526495630
OkHttp-Received-Millis: 1407526495721
Après OkHttp crée ce fichier, il conserve demande au serveur, la même ressource. Je peux voir ces messages dans Wireshark.
Ce que je fais mal?
Mise à JOUR:
C'est maintenant le temps de réponse du serveur après que Jesse suggestion:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Expires: Thu, 14 Aug 2014 18:06:05 GMT
Last-Modified: Sun, 10 Aug 2014 12:37:06 GMT
Content-Length: 281
Date: Wed, 13 Aug 2014 18:06:05 GMT
Mise à JOUR 2:
Essayé la version du code et découvert qu'il est tout à fait probable qu'il y est un bug quelque part au sujet de la cache. C'est ce que j'ai reçu de l'Maven de sortie:
Results :
Failed tests:
CacheTest.conditionalHitUpdatesCache:1653 expected:<[A]> but was:<[B]>
Tests in error:
CallTest.tearDown:86 » IO failed to delete file: C:\Users\Adrian\AppData\Local...
Tests run: 825, Failures: 1, Errors: 1, Skipped: 17
Plus complet du journal peut être vu ici: https://gist.github.com/16BITBoy/344ea4c22b543f397f53
source d'informationauteur Adrián Pérez | 2014-08-08
Vous devez vous connecter pour publier un commentaire.
Je viens de résoudre le problème. Il est quelque peu trompeuse que le cache de tests où à défaut lorsque j'ai essayé d'utiliser OkHttp à partir de la source.
Le problème était assez facile, et c'était un autre des méthodes de demande de a été d'obtenir un corps sur la réponse, et il n'était pas fermé à la fin. Ce qui explique pourquoi j'ai vu ".tmp" fichier dans le cache, mais encore confuse et trompeuse en raison du fait que cela demande de la méthode a été la consommation et de fermeture du corps de la réponse. Ses comme la serrure ou un moniteur pour le cache de l'éditeur est global pour l'ensemble des demandes, au lieu de l'être par la demande. Je pensais qu'il n'était pas quand j'ai lu le code, lorsqu'il a utilisé une valeur de hachage pour la demande comme une clé.
De toute façon, c'était ça 😀
À partir de maintenant, je vais essayer de coller à un modèle comme ça...
...avant le traitement de chaque cas pour le code de réponse. De cette façon, je ne vais pas manquer un appel à proximité du corps de la réponse.
Votre serveur est de forcer le cache de validation avec cet en-tête de réponse:
Supprimer cela et vous devriez être bon d'aller.
J'ai le même problème, alors je déboguer le okhttp code source, vous pouvez regarder le CacheStrategy.cacheResponseAge()okhttp utilisera le nowMillis et servedDatele servedDate est d'obtenir à partir de votre serveur http en-tête "Date", les nowMillis est d'obtenir à partir de votre appareil android. Alors, quand l'heure du serveur est plus tard que l'heure du dispositif, okhttp ne sera pas obtenir à partir du cache si max-age est faible.
pardonner mon mauvais anglais ^_^