2015-03-18 3 views
19

Я пытаюсь кэшировать ответ http-вызовов, выполненных Retrofit (v 1.9.0) с помощью OkHttp (2.3.0). Он всегда делал сетевые вызовы, если я пытаюсь позвонить без Интернета, тогда java.net.UnknownHostException.Retrofit - клиент Okhttp Как кэшировать ответ

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. 

    } 

Я последовал this. Но я не могу работать. Это просто удар с сервера. Что я делаю не так?

+0

Можете ли вы протестировать http://stackoverflow.com/a/23503804/3824335 и http://stackoverflow.com/a/22735632/3824335? – user2319066

+1

У меня возникли проблемы с заголовком Pragma и, наконец, нашел способ заставить его работать с удалением этого значения заголовка. Вот демонстрационный проект, который объединяет все концепции вместе с кем угодно. https://github.com/digitalbuddha/StoreDemo – FriendlyMikhail

ответ

37

В соответствии с Дополнением 1.9.0, который использует OkClient, не имеет поддержки кеширования. Мы должны использовать OkHttpClient экземпляр библиотеки Square OkHttpClient.

Вы можете скомпилировать по compile 'com.squareup.okhttp:okhttp:2.3.0'

, прежде чем все модернизированных кэша заголовков ответа как

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

** 120 секунд.

Вы можете прочитать больше о заголовках here.

заголовки Кэширование в основном проинструктированы ответа сервера. Попытайтесь внедрить кеш-заголовки на серверах. Если у вас нет опции, да, у нее есть модификация.

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

Где кэшировать:

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

Добавить перехватчик в OkHttpClient Например:

okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); 

И, наконец, добавить OkHttpClient к RestAdapter:

RestAdapter.setClient(new OkClient(okHttpClient)); 

И вы можете пройти через this слайд для получения дополнительной информации.

Смежные вопросы