Android 安卓技术分享网络Android开发

OkHttp高效开发介绍

2016-12-30  本文已影响279人  StChris

一.开启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请求&响应数据的方法

  1. 添加 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

上一篇 下一篇

猜你喜欢

热点阅读