Подтвердить что ты не робот

Retrofit - клиент Okhttp Как кэшировать ответ

Я пытаюсь кэшировать ответ http-вызовов, выполненных Retrofit (v 1.9.0) с помощью OkHttp (2.3.0). Он всегда делал сетевые вызовы, если я пытаюсь позвонить без Интернета, а затем 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;
}

}

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.

    } 

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

4b9b3361

Ответ 1

В соответствии с дооснащением 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 - секунды.

Подробнее о заголовках можно прочитать здесь.

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

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

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