2015-03-18 16 views
19

Sto tentando di memorizzare nella cache la risposta delle chiamate http eseguite da Retrofit (v 1.9.0) con OkHttp (2.3.0). Ha sempre effettuato le chiamate di rete se provo a effettuare una chiamata senza internet, quindi lo java.net.UnknownHostException.Retrofit - client Okhttp Come memorizzare nella cache la risposta

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; 
} 

} 

MyActivity

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. 

    } 

ho seguito this. Ma non riesco a lavorare. Sta semplicemente colpendo dal server. Che cosa sto facendo di sbagliato?

+0

Puoi testare http://stackoverflow.com/a/23503804/3824335 e http://stackoverflow.com/a/22735632/3824335? – user2319066

+1

Ho avuto alcuni problemi con l'intestazione di Pragma e finalmente ho trovato un modo per farlo funzionare con la rimozione di quel valore di intestazione. Ecco un progetto dimostrativo che riunisce tutti i concetti in chiunque ne abbia bisogno. https://github.com/digitalbuddha/StoreDemo – FriendlyMikhail

risposta

37

Come per Retrofit 1.9.0 che utilizza OkClient non supporta la memorizzazione nella cache. Dobbiamo utilizzare l'istanza OkHttpClient dalla libreria Square OkHttpClient.

è possibile compilare da compile 'com.squareup.okhttp:okhttp:2.3.0'

Prima di tutto cache di retrofit per le intestazioni di risposta come

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

** 120 è secondi.

Si può leggere di più su intestazioni here.

intestazioni di cache sono per lo più istruiti dalla risposta del server. Provare ad implementare le intestazioni della cache nei server. Se non si dispone di un'opzione, sì l'aggiornamento lo ha.

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(); 
    } 
}; 

Dove cache:

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”); 
} 

Aggiungere intercettore all'istanza OkHttpClient:

okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); 

E infine aggiungere OkHttpClient al RestAdapter:

RestAdapter.setClient(new OkClient(okHttpClient)); 

E si può passare attraverso la diapositiva this per ulteriore riferimento.

Problemi correlati