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
- ¿Usando OKHttp, cuál es la diferencia entre la petición síncrona en AsyncTask y la petición asíncrona de OKhttp?
- ¿Retrofit hace llamadas de red en el hilo principal?
- OkHttp con pinzado de certificado
- Retrofit "IllegalStateException: Ya ejecutado"
- Cómo agregar matriz a okhttp cuerpo (POST)
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?
- Retrofit + okhttp: Recuperar GZIPInputStream
- Cómo obtener el cuerpo de la respuesta en okhttp cuando el código es 401
- Cómo manejar el error auth0 403 sin agregar código específico en todas partes (Retrofit / okhttp / RxAndroid)
- Picasso no carga imágenes
- Causado por: java.lang.NoClassDefFoundError: Clase no encontrada usando el cargador de clase de arranque; No hay rastro de la pila disponible
- La imagen Captcha no se puede actualizar con Glide
- Proxy transparente para probar las respuestas del servidor sin conexión en Android
- No hay ningún error de este tipo al usar robospice-retrofit y getstream.io
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.
- Android Studio agrega un permiso no deseado después de ejecutar la aplicación en un dispositivo real
- ¿Cómo puedo evitar la ejecución de onTextChanged en el EditText de Android