之前我们分析了使用Retrofit怎么用OkHttp持久化管理Cookie,今天打算继续跟大家来分享一些关于怎么去设置OKHttp?如果你还不知道怎么持久化管理Cookie,请看这篇文章:Retrofit+OKHttp 教你怎么持久化管理Cookie,好了,废话不多说,开始今天的分享:
大家都知道Retrofit是Square公司基于OkHttp推出的一个高解耦的网络框架,至于为什么又出来一个这个东东,想必可能是觉得使用OKHttp一般都需要自己再包一层吧,当然你也可以不用再自己费劲去封装,因为网上很多大牛前辈已经做了,你可以看鸿洋大神封装的OKHttp,Android 一个改善的okHttp封装库,只要你能想到的,这里面都有,因为我已经用这个做过一个APP了。
切入正题:我们先看一下Retrofit里面都包括那些东西吧:
我们可以看到Retrofit里面东西非常少,http包里面的注解的东西,剩下的就这几个类和这几个接口,因为Retrofit把网络请求交给了OkHttp去做,我们来详细介绍一个这个类:
Call:
这个接口主要的作用就是发送一个Http请求,Retrofit的默认请求方式是OKHttpCall,当然你也可以根据自己的业务逻辑自己定义Call。
CallAdapter:
这个接口的主要作用就是将Call对象转化成另一个对象,原谅我的水平有限,没太看懂里面的代码
CallBack:
看接口名想必大家都能看出来,这是回掉接口,里面有两个回调方法
onResponse()
onFailure().
Converter:
这个接口主要的作用是将服务器返回数据解析为你所需要的JSON,XML等对象。
OkHttpCall:
OkHttpCall实现了上面的Call接口,通过这个类直接用OkHttp的request去执行网络请求,实现异步,同步请求,接口回调…
其它的一些类就不一一介绍了,毕竟这篇文章的主题不是源码解析,如果你想从源码的角度去了解Retrofit,我推荐你可以去看这两篇文章:
Retrofit2 完全解析 探索与okhttp之间的关系
Retrofit分析-漂亮的解耦套路
好了,我们看了Retrofit包里面并没有网络请求的部分,因为它是依赖OKHttp实现的一个网络框架,那么有关网络的一部分设置比如cookie的设置、网络超时的设置、请求header设置等等这些我们就该去设置OKHttp。
1.回顾一下之前的持久化管理cookie:
保存本地cookie:
CookieHandler cookieHandler = new CookieManager(new PersistentCookieStore(context), CookiePolicy.ACCEPT_ALL);
添加cookieJar:
.cookieJar(new JavaNetCookieJar(cookieHandler))
2.设置网络超时:
读、写、连接:
.readTimeout(10000, TimeUnit.MILLISECONDS) .connectTimeout(10000,TimeUnit.MILLISECONDS) .writeTimeout(1000,TimeUnit.MILLISECONDS)
3.设置HttpLoggingInterceptor拦截器:
我们可以设置拦截器来打印网络请求的返回结果:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY);
其中Interceptors的level是可以自行设置的:
注释写的很清楚了,就不废话了
public enum Level { /** No logs. */ NONE, /** * Logs request and response lines. * * <p>Example: * <pre>{@code * --> POST /greeting http/1.1 (3-byte body) * * <-- 200 OK (22ms, 6-byte body) * }</pre> */ BASIC, /** * Logs request and response lines and their respective headers. * * <p>Example: * <pre>{@code * --> POST /greeting http/1.1 * Host: example.com * Content-Type: plain/text * Content-Length: 3 * --> END POST * * <-- 200 OK (22ms) * Content-Type: plain/text * Content-Length: 6 * <-- END HTTP * }</pre> */ HEADERS, /** * Logs request and response lines and their respective headers and bodies (if present). * * <p>Example: * <pre>{@code * --> POST /greeting http/1.1 * Host: example.com * Content-Type: plain/text * Content-Length: 3 * * Hi? * --> END GET * * <-- 200 OK (22ms) * Content-Type: plain/text * Content-Length: 6 * * Hello! * <-- END HTTP * }</pre> */ BODY }
4.设置缓存:
File httpCacheDirectory = new File(UIUtils.getContext().getExternalCacheDir(), "xxx"); client.setCache(new Cache(httpCacheDirectory,10 * 1024 * 1024));
先获取系统外部存储的路径,”xxx”可以自己命名,文件夹可以在 android/data/<包名>/cache/resposes 看到里面的内容。
Request request = chain.request(); if (!AppUtil.isNetworkReachable(UIUtils.getContext())) { request = request.newBuilder() .cacheControl(CacheControl.FORCE_CACHE) .url(path).build(); UIUtils.showToastSafe("暂无网络"); }
Response response = chain.proceed(request); if(AppUtil.isNetworkReachable(UIUtils.getContext())) { int maxAge = 60 * 60; // read from cache for 60 minute response.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public, max-age=" + maxAge) .build(); } else { int maxStale = 60 * 60 * 24 * 7; // tolerate 4-weeks stale response.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) .build(); }
先判断网络,网络好的时候,移除header后添加haunch失效时间为1小时,网络未连接的情况下设置缓存时间为7天。
5.设置通用Header
Retrofit 2.0支持在每个方法的上面添加注解设置头
@Headers("Content-Type: application/json")
很显然这样比较麻烦,那么你可以这样:
通过拦截器来设置头
OkHttpClient httpClient = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request() .newBuilder() .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") .addHeader("Accept-Encoding", "gzip, deflate") .addHeader("Connection", "keep-alive") .addHeader("Accept", "*/*") .addHeader("Cookie", "add cookies here") .build(); return chain.proceed(request); } }) .build();
好了,目前用到的就这么多了,如果后期有其他的会再加上,如果有错误的地方或者不合适的地方希望大家多多指正,留言交流,也可以加群交流。