Próbuję użyć Retrofit & OKHttp do buforowania odpowiedzi HTTP. Podążałem za tym sednem i skończyłem z tym kodem:
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
HttpResponseCache httpResponseCache = null;
try {
httpResponseCache = new HttpResponseCache(httpCacheDirectory, 10 * 1024 * 1024);
} catch (IOException e) {
Log.e("Retrofit", "Could not create http cache", e);
}
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setResponseCache(httpResponseCache);
api = new RestAdapter.Builder()
.setEndpoint(API_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(okHttpClient))
.build()
.create(MyApi.class);
A to jest MyApi z nagłówkami Cache-Control
public interface MyApi {
@Headers("Cache-Control: public, max-age=640000, s-maxage=640000 , max-stale=2419200")
@GET("/api/v1/person/1/")
void requestPerson(
Callback<Person> callback
);
Najpierw żądam online i sprawdzam pliki pamięci podręcznej. Znajduje się tam poprawna odpowiedź JSON i nagłówki. Ale kiedy próbuję poprosić o dostęp offline, zawsze otrzymuję RetrofitError UnknownHostException
. Czy jest jeszcze coś, co powinienem zrobić, aby Retrofit odczytywał odpowiedź z pamięci podręcznej?
EDYCJA:
Ponieważ OKHttp 2.0.x HttpResponseCache
jest Cache
, setResponseCache
jestsetCache
Cache-Control: s-maxage=1209600, max-age=1209600
, nie wiem, czy to wystarczy.public
słowo kluczowe musiało znajdować się w nagłówku odpowiedzi, aby działało w trybie offline. Ale te nagłówki nie pozwalają OkClient na korzystanie z sieci, gdy jest dostępna. Czy mimo to można ustawić zasady / strategię pamięci podręcznej w celu korzystania z sieci, gdy jest dostępna?max-stale + max-age
zostanie przekazane, żąda z sieci. Ale chcę ustawić maksymalny czas na tydzień. To sprawia, że odczytuje odpowiedź z pamięci podręcznej, nawet jeśli jest dostępna sieć.Odpowiedzi:
Edycja dla Retrofit 2.x:
OkHttp Interceptor to właściwy sposób na dostęp do pamięci podręcznej w trybie offline:
1) Utwórz Interceptor:
2) Konfiguracja klienta:
3) Dodaj klienta do modernizacji
Należy również sprawdzić @kosiara - Bartosz Kosarzycki „s odpowiedź . Może być konieczne usunięcie nagłówka z odpowiedzi.
OKHttp 2.0.x (Sprawdź oryginalną odpowiedź):
Ponieważ OKHttp 2.0.x
HttpResponseCache
jestCache
,setResponseCache
jestsetCache
. Więc powinieneśsetCache
polubić to:Oryginalna odpowiedź:
Okazuje się, że odpowiedź serwera musi
Cache-Control: public
wykonaćOkClient
odczyt z pamięci podręcznej.Ponadto, jeśli chcesz żądać z sieci, gdy jest dostępna, powinieneś dodać
Cache-Control: max-age=0
nagłówek żądania. Ta odpowiedź pokazuje, jak to zrobić sparametryzowane. Tak to wykorzystałem:źródło
HttpResponseCache has been renamed to Cache.** Install it with OkHttpClient.setCache(...) instead of OkHttpClient.setResponseCache(...)
.if (Utils.isNetworkAvailable(context))
poprawne, czy ma być odwrócone tj.if (!Utils.isNetworkAvailable(context))
?public okhttp3.Response intercept(Chain chain) throws IOException
nigdy nieWszystkie powyższe odpowiedzi nie działają dla mnie. Próbowałem zaimplementować pamięć podręczną offline w modernizacji 2.0.0-beta2 . Dodałem przechwytywacz za pomocą
okHttpClient.networkInterceptors()
metody, ale otrzymałem,java.net.UnknownHostException
gdy próbowałem użyć pamięci podręcznej w trybie offline. Okazało się, że muszę też dodaćokHttpClient.interceptors()
.Problem polegał na tym, że pamięć podręczna nie została zapisana w pamięci flash, ponieważ serwer zwrócił,
Pragma:no-cache
co uniemożliwia OkHttp przechowywanie odpowiedzi. Pamięć podręczna offline nie działała nawet po zmodyfikowaniu wartości nagłówka żądania. Po kilku próbach i błędach udało mi się uruchomić pamięć podręczną bez modyfikowania strony zaplecza, usuwając pragmę z odpowiedzi zamiast żądania -response.newBuilder().removeHeader("Pragma");
Modernizacja: 2.0.0-beta2 ; OkHttp: 2.5.0
...
...
źródło
interceptors ()
inetworkInterceptors ()
są identyczne. Dlaczego to zduplikowałeś?.networkInterceptors().add()
iinterceptors().add()
?Moje rozwiązanie:
źródło
Odpowiedź brzmi TAK, na podstawie powyższych odpowiedzi zacząłem pisać testy jednostkowe, aby zweryfikować wszystkie możliwe przypadki użycia:
Zbudowałem małą bibliotekę pomocniczą, aby łatwo skonfigurować pamięć podręczną OKHttp, możesz zobaczyć powiązane unittest tutaj na Github: https://github.com/ncornette/OkCacheControl/blob/master/okcache-control/src/test/java/com/ ncornette / cache / OkCacheControlTest.java
Unittest, który demonstruje użycie pamięci podręcznej w trybie offline:
Jak widać, pamięci podręcznej można używać, nawet jeśli wygasła. Mam nadzieję, że to pomoże.
źródło
Opierając się na odpowiedzi @ kosiara-bartosz-kasarzycki , stworzyłem przykładowy projekt, który poprawnie ładuje się z pamięci-> dysk-> sieci przy użyciu retrofit, okhttp, rxjava i guava. https://github.com/digitalbuddha/StoreDemo
źródło
Pamięć podręczna z Retrofit2 i OkHTTP3:
NetworkUtils.isNetworkAvailable () metoda statyczna:
Następnie po prostu dodaj klienta do konstruktora modernizacji:
Oryginalne źródło: https://newfivefour.com/android-retrofit2-okhttp3-cache-network-request-offline.html
źródło