Я пытаюсь использовать Retrofit & OKHttp для кэширования HTTP-ответов. Я следовал этой сути и, в конечном итоге, с этим кодом:
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);
И это MyApi с заголовками 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
);
Сначала я запрашиваю онлайн и проверяю файлы кеша. Правильный ответ JSON и заголовки там. Но когда я пытаюсь запросить в автономном режиме, я всегда получаю RetrofitError UnknownHostException
. Что еще я должен сделать, чтобы Retrofit прочитал ответ из кеша?
РЕДАКТИРОВАТЬ:
Так как OKHttp 2.0.x HttpResponseCache
есть Cache
, setResponseCache
естьsetCache
Cache-Control: s-maxage=1209600, max-age=1209600
я не знаю, достаточно ли этого.public
ключевое слово нужно было в заголовке ответа, чтобы оно работало в автономном режиме. Но эти заголовки не позволяют OkClient использовать сеть, когда она доступна. Есть ли способ установить политику / стратегию кэширования для использования сети, когда она доступна?max-stale + max-age
пропущен, он делает запрос из сети. Но я хочу установить max-stale неделю. Это делает чтение ответа из кэша, даже если сеть доступна.Ответы:
Изменить для Retrofit 2.x:
OkHttp Interceptor - это правильный способ доступа к кешу в автономном режиме:
1) Создать перехватчик:
2) Настройка клиента:
3) Добавить клиента для модернизации
Также проверьте @kosiara - Бартош Kosarzycki «s ответ . Возможно, вам придется удалить заголовок из ответа.
OKHttp 2.0.x (проверьте оригинальный ответ):
Так как OKHttp 2.0.x
HttpResponseCache
естьCache
,setResponseCache
естьsetCache
. Так что вам должноsetCache
понравиться это:Оригинальный ответ:
Оказывается, ответ сервера должен быть
Cache-Control: public
сделанOkClient
для чтения из кеша.Кроме того, если вы хотите запросить из сети, когда доступно, вы должны добавить
Cache-Control: max-age=0
заголовок запроса. Этот ответ показывает, как это сделать параметризованным. Вот как я это использовал:источник
HttpResponseCache has been renamed to Cache.** Install it with OkHttpClient.setCache(...) instead of OkHttpClient.setResponseCache(...)
.if (Utils.isNetworkAvailable(context))
правильно или это должно быть наоборот то естьif (!Utils.isNetworkAvailable(context))
?public okhttp3.Response intercept(Chain chain) throws IOException
никогда не вызывается, он вызывается только тогда, когда я в сетиВсе вышеописанные у меня не сработали. Я пытался реализовать автономный кеш в модификации 2.0.0-бета2 . Я добавил перехватчик, используя
okHttpClient.networkInterceptors()
метод, но получил,java.net.UnknownHostException
когда я пытался использовать кэш в автономном режиме. Оказалось, что я должен был добавитьokHttpClient.interceptors()
также.Проблема заключалась в том, что кэш не был записан во флэш-память, потому что сервер вернулся,
Pragma:no-cache
что не позволяет OkHttp хранить ответ. Автономный кеш не работал даже после изменения значений заголовка запроса. После некоторых проб и ошибок я заставил кеш работать без изменения серверной части, удалив прагму из ответа вместо запроса -response.newBuilder().removeHeader("Pragma");
Дооснащение: 2.0.0-бета2 ; OkHttp: 2.5.0
...
...
источник
interceptors ()
иnetworkInterceptors ()
идентичны. Почему ты продублировал это?.networkInterceptors().add()
иinterceptors().add()
?Мое решение:
источник
Ответ ДА. На основании приведенных выше ответов я начал писать модульные тесты для проверки всех возможных вариантов использования:
Я создал небольшую вспомогательную библиотеку для легкой настройки кэша OKHttp. Вы можете увидеть соответствующий юнит-тест здесь на Github: https://github.com/ncornette/OkCacheControl/blob/master/okcache-control/src/test/java/com/ ncornette / кэш / OkCacheControlTest.java
Unittest, который демонстрирует использование кэша в автономном режиме:
Как видите, кеш можно использовать, даже если срок его действия истек. Надеюсь, это поможет.
источник
опираясь на @ kosiara-Бартош-kasarzycki в ответ , я создал образец проекта , который должным образом грузы из Memory-> диск-> сеть с использованием модифицированной, okhttp, rxjava и гуавы. https://github.com/digitalbuddha/StoreDemo
источник
Кэш с Retrofit2 и OkHTTP3:
Статический метод NetworkUtils.isNetworkAvailable ():
Затем просто добавьте клиента в модификатор сборки:
Первоисточник: https://newfivefour.com/android-retrofit2-okhttp3-cache-network-request-offline.html
источник