2015-03-18 12 views
19

Ich versuche, die Antwort von HTTP-Aufrufen von Retrofit (v 1.9.0) mit OkHttp (2.3.0) zu cachen. Es hat immer die Netzwerkanrufe gemacht, wenn ich versuche, einen Anruf ohne Internet dann java.net.UnknownHostException zu machen.Retrofit - Okhttp client Wie man die Antwort zwischenspeichert

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. 

    } 

folgte ich this. Aber ich kann nicht arbeiten. Es trifft einfach vom Server. Was mache ich falsch?

+0

Können Sie http://stackoverflow.com/a/23503804/3824335 und http://stackoverflow.com/a/22735632/3824335 testen? – user2319066

+1

Ich hatte einige Probleme mit Pragma-Header und fand schließlich einen Weg, es mit dem Entfernen dieses Header-Wertes arbeiten zu lassen. Hier ist ein Demo-Projekt, das alle Konzepte zusammenbringt, damit jeder es braucht. https://github.com/digitalbuddha/StoreDemo – FriendlyMikhail

Antwort

37

Nach Retrofit 1.9.0, die OkClient verwendet, hat keine Caching-Unterstützung. Wir müssen OkHttpClient Instanz von Square OkHttpClient Bibliothek verwenden.

Sie können compile 'com.squareup.okhttp:okhttp:2.3.0'

Vor allem Nachrüst-Caches durch Response-Header wie

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

** 120 Sekunden kompilieren.

Sie können mehr über Header lesen here.

Caching-Header werden meist durch Server-Antwort angewiesen. Versuchen Sie, Cache-Header in Servern zu implementieren. Wenn Sie keine Option haben, ja Nachrüstung hat es.

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

Wo zwischenzuspeichern:

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

Abfangjäger zum OkHttpClient Instanz hinzufügen:

okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); 

Und schließlich OkHttpClient zum RestAdapter hinzufügen:

RestAdapter.setClient(new OkClient(okHttpClient)); 

Und Sie können durch this Folie für mehr Referenz gehen.

Verwandte Themen