In the first Retrofit caching tutorial we've given you an overview on how caching works and what steps are necessary to enable it for Retrofit. We've skipped one important information: how can you detect whether a response came from the cache, the server, or even both?
In this tutorial, you'll learn the answer to this question.
Retrofit Series Overview
- Getting Started and Creating an Android Client
- Basics of API Description
- Creating a Sustainable Android Client
- URL Handling, Resolution and Parsing
- How to Change API Base Url at Runtime
- Multiple Server Environments (Develop, Staging, Production)
- Share OkHttp Client and Converters between Retrofit Instances
- Upgrade Guide from 1.9
- Beyond Android: Retrofit for Java Projects
- How to use OkHttp 3 with Retrofit 1
- Synchronous and Asynchronous Requests
- Send Objects in Request Body
- Add Custom Request Header
- Manage Request Headers in OkHttp Interceptor
- Dynamic Request Headers with @HeaderMap
- Multiple Query Parameters of Same Name
- Optional Query Parameters
- Send Data Form-Urlencoded
- Send Data Form-Urlencoded Using FieldMap
- How to Add Query Parameters to Every Request
- Add Multiple Query Parameter With QueryMap
- How to Use Dynamic Urls for Requests
- Constant, Default and Logic Values for POST and PUT Requests
- Cancel Requests
- Reuse and Analyze Requests
- Optional Path Parameters
- How to Send Plain Text Request Body
- Customize Network Timeouts
- How to Trust Unsafe SSL certificates (Self-signed, Expired)
- Dynamic Endpoint-Dependent Interceptor Actions
- How to Update Objects on the Server (PUT vs. PATCH)
- How to Delete Objects on the Server
- Introduction to (Multiple) Converters
- Adding & Customizing the Gson Converter
- Implementing Custom Converters
- How to Integrate XML Converter
- Access Mapped Objects and Raw Response Payload
- Supporting JSON and XML Responses Concurrently
- Handling of Empty Server Responses with Custom Converter
- Send JSON Requests and Receive XML Responses (or vice versa)
- Unwrapping Envelope Responses with Custom Converter
- Wrapping Requests in Envelope with Custom Converter
- Define a Custom Response Converter
- Activate Response Caching (Etag, Last-Modified)
- Check Response Origin (Network, Cache, or Both)
- Force Server Cache Support with Response Interceptor
- Support App Offline Mode by Accessing Response Caches
- Analyze Cache Files
Check Response Origin
It can be interesting to know whether a response came from the server or from the cache. Not only when building apps with offline functionality, where all responses are cached for times without Internet connection, but also for the regular use of saving bandwidth and time. In either case, Retrofit does not give you a direct answer. You've to figure out the origin by combining some clues.
Indirect Check with Raw Response
In general, your async Retrofit call will look like this:
Call<ResponseBody> call = //...
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
// success, server (or cache) responded
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// failure, no network connection or conversion threw error
}
});
When the network request was a success, you've access to the response
object. This is Retrofit's Response
class, which won't reveal any information relevant to caching. However, you can go down a level by calling response.raw()
, which gives you the network layers OkHttp's response object.
OkHttp's response object gives you two helper methods to analze the caching situation of the request: cacheResponse()
and networkResponse()
.
if (response.raw().cacheResponse() != null) {
// true: response was served from cache
}
if (response.raw().networkResponse() != null) {
// true: response was served from network/server
}
The functionality should be obvious, if cacheResponse()
is not null
, the response came from the cache. If networkResponse()
is not null
, the response came from the server.
You might ask, couldn't I've done this in a single if
-else
case? No, because both methods can return true! This happens when Retrofit and OkHttp made a conditional request. That means the cached version wasn't guaranteed to be valid anymore, but the server responded with a 304 - Not Modified
header, which indicates that the cached version is still valid. Thus, the resource content came from cache, but the headers came from the server.
You can use the information whether the resource came from cache to further enhance your app's user experience.
Summary
In this tutorial you've learned how to check if a response came from the server or from OkHttp's cache. Depending on your use case, it might be beneficial to the user to know whether the data is completely up-to-date or just a cached version.
Do you have further questions on this topic or about Retrofit in general? Just let us know on Twitter @futurestud_io or leave a comment below.
Enjoy coding & make it rock!