一.开启OKHttp缓存
OKHTTP有自己的网络缓存机制,针对GET请求 有网时 获取数据并缓存,没网时会看是否有缓存,有缓存则返回缓存的数据。
1.设置缓存
/**
* 设缓存有效期为两天
*/
private static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;
// 指定缓存路径,缓存大小100Mb
Cache cache = new Cache(new File(BaseApplication.context().getCacheDir(), "HttpCache"),
1024 * 1024 * 50);
2.设置拦截器(缓存)
* 云端响应头拦截器,用来配置缓存策略
* Dangerous interceptor that rewrites the server's cache-control header.
*/
private Interceptor mRewriteCacheControlInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response originalResponse = chain.proceed(request);
if (NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
//有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
String cacheControl = request.cacheControl().toString();
return originalResponse.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();
} else {
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + CACHE_STALE_SEC)
.removeHeader("Pragma")
.build();
}
}
};
3.加上网络超时配置就可以了
OkHttpClient okHttpClient = new OkHttpClient.Builder()
//网络超时
.readTimeout(5000, TimeUnit.MILLISECONDS)
.connectTimeout(5000,TimeUnit.MILLISECONDS)
.writeTimeout(5000,TimeUnit.MILLISECONDS)
//网络缓存
.addInterceptor(mRewriteCacheControlInterceptor)
.addNetworkInterceptor(mRewriteCacheControlInterceptor)
//缓存
.cache(cache)
.build();
二.观察HTTP请求&响应数据的方法
-
添加 HttpLoggingInterceptor
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); //包含header、body数据 loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); //在build OkHttpClient的时候加入Log拦截器 OkHttpClient.Builder().addInterceptor(loggingInterceptor)
HttpLoggingInterceptor的效果如下图,开发时如果需要看整个App的所有请求及相应,可以使用okhttp关键字过滤
注意!这样设置 有时会有问题!!!
(1).会报错
java.lang.NoSuchMethodError: No virtual method log(Ljava/lang/String;)V in class Lokhttp3/internal/Platform; or its super classes
把retrofit依赖包改为2.0.1后,问题迎刃而解
(2).打印不出网络请求日志 可以按如下修改
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.e("okhttp", message);
}
});
2.自定义Interceptor
// 打印返回的json数据拦截器
private Interceptor mLoggingInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
Request signedRequest = requestBuilder
.build();
okhttp3.Response response = chain.proceed(signedRequest);
MediaType contentType = null;
String bodyString = null;
if (response.body() != null) {
contentType = response.body().contentType();
bodyString = response.body().string();
}
// 注意!
// 我只打印了 GET POSt 方法
switch (request.method()) {
case "GET":
Log.e("retrofit-->",
"GET "+ signedRequest.url()+" -->"+
bodyString);
break;
case "POST":
Log.e("retrofit-->",
"POST "+ signedRequest.url()+" -->"+
bodyToString(signedRequest)+" -->"+
bodyString);
break;
}
if (response.body() != null) {
// 深坑!
// 打印body后原ResponseBody会被清空,需要重新设置body
ResponseBody body = ResponseBody.create(contentType, bodyString);
return response.newBuilder().body(body).build();
} else {
return response;
}
}
};
private static String bodyToString(final Request request){
try {
final Buffer buffer = new Buffer();
request.body().writeTo(buffer);
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}
//在build OkHttpClient的时候加入Log拦截器
OkHttpClient.Builder().addInterceptor(mLoggingInterceptor );
3.Facebook强大的监测工具:Stetho(有兴趣的可以多看看 Stetho 这里只讲拦截)
(1) 在build OkHttpClient时需要添加网络拦截器
OkHttpClient.Builder().addNetworkInterceptor(new StethoInterceptor())
(2) 在Application的OnCreate中初始化
//FaceBook调试器,可在Chrome调试网络请求,查看SharePreferences,数据库等
Stetho.initializeWithDefaults(this);
(3) 连接手机,在Chrome中打开chome://inspect/#devices
看到如下界面,则代表监测成功,如果没有App显示,那应该就是忘了在Application中初始化Stetho