2017-01-18 9 views
11

Есть ли способ обнаружить, что ответ Retrofit приходит из сконфигурированного кэша OkHttp или является живым ответом?Обнаруживать, если ответ OkHttp приходит из кеша (с помощью дооснащения)

определение

Клиент:

Cache cache = new Cache(getCacheDirectory(context), 1024 * 1024 * 10); 
OkHttpClient okHttpClient = new OkHttpClient.Builder() 
      .cache(cache) 
      .build(); 

определение Апи:

@GET("/object") 
Observable<Result<SomeObject>> getSomeObject(); 

Пример вызова:

RetroApi retroApi = new Retrofit.Builder() 
      .client(okHttpClient) 
      .baseUrl(baseUrl) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .build() 
      .create(RetroApi.class); 

result = retroApi.getSomeObject().subscribe((Result<SomeObject> someObjectResult) -> { 
    isFromCache(someObjectResult); // ??? 
}); 

ответ

13

Каждый раз, когда у вас есть okhttp3.Response (retrofit2.Response.raw()), вы можете проверить, является ли ответ из кэша.

Цитирую Джесси Уилсон:

Есть несколько комбо.

.networkResponse()только - ваш запрос был подан только из сети.

.cacheResponse()только - ваш запрос был подан только из кеша.

.networkResponse() и .cacheResponse() - ваш запрос был условным GET, поэтому заголовки из сети и тела из кеша.

Так для примера, метод isFromCache будет выглядеть так:

boolean isFromCache(Result<?> result) { 
    return result.response().raw().networkResponse() == null; 
} 
+0

Эта цитата исходит из разговора или какого-либо другого онлайн-ресурса? Если да, не могли бы вы предоставить ссылку? – user2340612

+0

На самом деле лучше проверить 'result.response(). Raw(). CacheResponse()! = Null'. Если клиент повторно проверяет кешированный ответ и получает 304, оба параметра «networkResponse()» и «cacheResponse()» будут не равными нулю. – apottere

+0

Да, в зависимости от семантики и вашего поведения в приложении. –

8

Раствор 1:

С помощью okhttp3.Response.cacheResponse() вы можете проверить, был ли получен ответ от кеша:

Возвращает необработанный ответ, полученный из кеша. Будет ли нулевое значение, если этот ответ не использовать кэш

Чтобы получить необработанный ответ OkHttp от вашего дооснащения Response obect использовать .raw(). т.е .:

public boolean isFromCache(Result<?> retroResult) { 
    return retroResult.response().raw().cacheResponse() != null; 
} 

Решение 2:

Вы можете добавить перехватчик Клиенту OkHttp через new OkHttpClient.Builder().addInterceptor(...). В этом перехватчике получить ответ через chain.proceed(chain.request). Затем используйте Response.cacheResponse(), соответственно Response.networkResponse(), чтобы определить, откуда пришел ответ.

Полный код:

new OkHttpClient.Builder().addInterceptor(chain -> { 
     Response response = chain.proceed(chain.request()); 
     if (response.cacheControl() != null) { 
      // from cache 
     } else if (response.networkResponse() != null) { 
      // from network 
     } 
     return response; 
}); 
+2

это всегда указывает на то, что ответ исходит из кеша! Даже если я удалю приложение! – Fakher

+1

его не работает –

+1

всегда отображается ответ от кеша –

1
if (response.raw().cacheResponse() != null) { 
    // true: response was served from cache 
} 

if (response.raw().networkResponse() != null) { 
    // true: response was served from network/server 
} 

Но я хотел бы предложить вам проверить, если ваш networkResponse является недействительным, так как только запрос кэшируется и у вас есть networkResponse, ваш ответ, переданный по потоку, связан с сетью и не кешем (в зависимости от maxStale, который вы могли бы указать на CacheControl). Поэтому проверьте, не является ли networkResponse нулевым, если null и ваш cacheResponse не являются нулевыми, ответ будет отправлен из кэша иначе наоборот.

 Смежные вопросы

  • Нет связанных вопросов^_^