Retrofit – Cliente Okhttp Cómo almacenar en caché la respuesta

Estoy intentando almacenar en caché la respuesta de las llamadas de http hechas por Retrofit (v 1.9.0) con OkHttp (2.3.0). Siempre hacía las llamadas de red si trataba de hacer una llamada sin internet entonces java.net.UnknownHostException .

RestClient

 public class RestClient { public static final String BASE_URL = "http://something.example.net/JSONService"; private com.ucc.application.rest.ApiService apiService; public RestClient() { Gson gson = new GsonBuilder() .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'") .create(); RequestInterceptor requestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestFacade request) { request.addHeader("Accept", "application/json"); int maxAge = 60 * 60; request.addHeader("Cache-Control", "public, max-age=" + maxAge); } }; RestAdapter restAdapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint(BASE_URL) .setClient(new OkClient(OkHttpSingleTonClass.getOkHttpClient())) .setConverter(new GsonConverter(gson)) .setRequestInterceptor(requestInterceptor) .build(); apiService = restAdapter.create(com.ucc.application.rest.ApiService.class); } public com.ucc.application.rest.ApiService getApiService() { return apiService; } } 

OkHttpSingleTonClass

 public class OkHttpSingleTonClass { private static OkHttpClient okHttpClient; private OkHttpSingleTonClass() { } public static OkHttpClient getOkHttpClient() { if (okHttpClient == null) { okHttpClient = new OkHttpClient(); createCacheForOkHTTP(); } return okHttpClient; } private static void createCacheForOkHTTP() { Cache cache = null; cache = new Cache(getDirectory(), 1024 * 1024 * 10); okHttpClient.setCache(cache); } public static File getDirectory() { final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "UCC" + File.separator); root.mkdirs(); final String fname = UserUtil.CACHE_FILE_NAME; final File sdImageMainDirectory = new File(root, fname); return sdImageMainDirectory; } } 

Mi actividad

 Request request = new Request.Builder() .cacheControl(new CacheControl.Builder() .onlyIfCached() .maxAge(60 * 60, TimeUnit.SECONDS) .build()) .url(RestClient.BASE_URL + Constants.GET_ABOUT_US_COLLECTION + "?userid=59e41b02-35ed-4962-8517-2668b5e8dae3&languageid=488d8f13-ef7d-4a3a-9516-0e0d24cbc720") .build(); Log.d("url_request", RestClient.BASE_URL + Constants.GET_ABOUT_US_COLLECTION + "/?userid=10"); com.squareup.okhttp.Response forceCacheResponse = null; try { forceCacheResponse = OkHttpSingleTonClass.getOkHttpClient().newCall(request).execute(); } catch (IOException e) { e.printStackTrace(); } if (forceCacheResponse.code() != 504) { // The resource was cached! Show it. Log.d("From", "Local"); Toast.makeText(AboutUs.this, "Local", Toast.LENGTH_SHORT).show(); } else { // The resource was not cached. Log.d("From", "Network"); Toast.makeText(AboutUs.this, "Network", Toast.LENGTH_SHORT).show(); getAbouUsDetails();//This will use the Apiservice interface to hit the server. } 

Lo seguí. Pero no puedo trabajar. Su simplemente golpear desde el servidor. ¿Qué estoy haciendo mal?

Según Retrofit 1.9.0 que utiliza OkClient no tiene soporte de caché. Tenemos que usar la instancia OkHttpClient por la biblioteca Square OkHttpClient .

Puede compilar por compile 'com.squareup.okhttp:okhttp:2.3.0'

Antes de todo, las cabeceras de respuesta

Cache-Control:max-age=120,only-if-cached,max-stale

** 120 es segundos.

Puede leer más acerca de encabezados aquí.

Los encabezados de almacenamiento en caché son instruidos principalmente por la respuesta del servidor. Trate de implementar encabezados de caché en los servidores. Si no tiene una opción, sí retrofit la tiene.

 private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response originalResponse = chain.proceed(chain.request()); return originalResponse.newBuilder() .header("Cache-Control", String.format("max-age=%d, only-if-cached, max-stale=%d", 120, 0)) .build(); } }; 

Dónde almacenar en caché:

 private static void createCacheForOkHTTP() { Cache cache = null; cache = new Cache(getDirectory(), 1024 * 1024 * 10); okHttpClient.setCache(cache); } // returns the file to store cached details private File getDirectory() { return new File(“location”); } 

Agregue interceptor a la instancia OkHttpClient:

 okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); 

Y finalmente agrega OkHttpClient al RestAdapter:

 RestAdapter.setClient(new OkClient(okHttpClient)); 

Y usted puede ir a través de esta diapositiva para más referencia.

  • Conexión cerrada por peer (Android 5)
  • ¿Debemos usar el proveedor de seguridad de google con OkHttp?
  • Cargue archivos en el cubo AWS S3 usando OkHttp o Retrofit
  • Añadir cookie a la solicitud del cliente OkHttp
  • PATCH Verb en Android (OkHttp, Volley, Retrofit ...)
  • Glide - agregar cabecera a la solicitud
  • Ninguna excepción de clase encontrada com.squareup.okhttp.logging.HttpLoggingInterceptor
  • Android OkHttp cómo manejar ETag
  • Respuesta de lectura por push de servidor con OkHttp
  • HTTPS no envía algunos encabezados de autenticación con Retrofit
  • Hacer la solicitud HTTP usando la biblioteca OkHttp dentro de doInBackground () de AsyncTask bloquea la operación de la interfaz de usuario
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.