简体   繁体   English

改造 - Okhttp客户端如何缓存响应

[英]Retrofit - Okhttp client How to cache the response

I'm trying to cache the response of http calls done by Retrofit(v 1.9.0) with OkHttp(2.3.0). 我正在尝试缓存由Retrofit(v 1.9.0)和OkHttp(2.3.0)完成的http调用的响应。 It always made the network calls if I try to make a call without internet then java.net.UnknownHostException . 如果我尝试在没有互联网的情况下进行呼叫,那么它总是进行网络呼叫,然后是java.net.UnknownHostException

RestClient 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 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 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.

    } 

I followed this . 我跟着这个 But I can't manage to work. 但我无法工作。 Its simply hitting from the server. 它只是从服务器上打。 What am i doing wrong? 我究竟做错了什么?

As per Retrofit 1.9.0 which uses OkClient does not have Caching support. 根据使用OkClient Retrofit 1.9.0没有缓存支持。 We have to use OkHttpClient instance by Square OkHttpClient library. 我们必须使用Square OkHttpClient库的OkHttpClient实例。

You can compile by compile 'com.squareup.okhttp:okhttp:2.3.0' 您可以通过compile 'com.squareup.okhttp:okhttp:2.3.0'进行compile 'com.squareup.okhttp:okhttp:2.3.0'

Before everything retrofit caches by response headers like 在通过响应头之类的所有内容改进缓存之前

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

** 120 is seconds. ** 120秒。

You can read more about headers here. 您可以在此处详细了解标题

Caching headers are mostly instructed by server response. 缓存标头主要由服务器响应指示。 Try to implement cache headers in servers. 尝试在服务器中实现缓存标头。 If you don't have an option, yes retrofit has it. 如果您没有选择,是的改造有它。

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

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

Add interceptor to the OkHttpClient instance: 将拦截器添加到OkHttpClient实例:

okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);

And finally add OkHttpClient to the RestAdapter: 最后将OkHttpClient添加到RestAdapter:

RestAdapter.setClient(new OkClient(okHttpClient));

And you can go through this slide for more reference. 您可以浏览幻灯片以获取更多参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM