【Android】の基础——OkHttp

来源:互联网 发布:ubuntu卸载程序命令 编辑:程序博客网 时间:2024/06/06 10:01

  • OkHttp使用
    • 同步方式
    • 异步方式
    • 拦截器
  • OkHttp请求过程解析
    • Dispatcher类
    • 同步请求的执行流程
    • 异步请求的执行流程
  • Volley和OkHttp对比
      • Volley
      • OkHttp

OkHttp使用

同步方式

OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();        Request request = new Request.Builder().url("http://www.baidu.com")                .get().build();        Call call = client.newCall(request);        try {            Response response = call.execute();            System.out.println(response.body().string());        } catch (IOException e) {            e.printStackTrace();        }

异步方式

OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();        Request request = new Request.Builder().url("http://www.baidu.com")                .get().build();        Call call = client.newCall(request);        call.enqueue(new Callback() {            @Override            public void onFailure(Call call, IOException e) {                System.out.println("Fail");            }            @Override            public void onResponse(Call call, Response response) throws IOException {                System.out.println(response.body().string());            }        });

拦截器

这里写图片描述

OkHttp请求过程解析

这里写图片描述

Dispatcher类

内部有一个线程池和三个队列,分别是readyAsyncCallsrunningAsyncCallsrunningSyncCalls队列

  • runningSyncCalls用于存储同步请求RealCall对象;
  • runningAsyncCalls队列用于存储进入队列的异步请求AsyncCall对象;
  • readyAsyncCalls队列用于当runningAsyncCalls的尺寸达到maxRequests参数时(默认64)存储新加的异步请求。

同步请求的执行流程

  1. excute()方法中,先判断是否执行过,如果执行过抛出异常并excuted=true;
  2. 接下来调用OkHttpClient的dispatcher()方法获得Dispatcher对象并调用其executed(RealCall)方法;
  3. 然后通过getResponseWithInterceptorChain()方法同步获取响应;
  4. 最后调用Dispatcher的finished()方法。

Dispatcher在excuted()的时候只是将同步请求加入到了runningSyncCalls队列。
finished()方法做的是从队列中移除请求,并获得还在运行的请求数量。如果没有在运行的请求,执行idleCallback的run()方法。

异步请求的执行流程

  1. enqueue()方法同样先将executed参数设为true
  2. 然后调用Dispatcher的enqueue(AsyncCall)方法,传入了一个AsyncCall对象。

    • AsyncCall继承NamedRunnable,实现了execute()方法(这个方法Runnable的run中被调用):
      1. 首先调用getResponseWithInterceptorChain()方法获取响应,成功后回调onReponse(),失败回调的onFailure();
      2. 最后,调用Dispatcher的finished()

那么在enqueue(AsyncCall)方法中:
首先如果正在运行的异步请求的数量符合放入runningAsyncCalls队列的要求,那么放入队列,然后将AsyncCall交给线程池;否则,放入readyAsyncCalls队列;
当线程池执行AsyncCall任务时,它的execute()方法会被调用,getResponseWithInterceptorChain()会去获取响应,最后调用Dispatcher的finished()方法 。
finished()方法中与同步请求不同的是,会调用promoteCalls(),遍历等待队列将请求移动到异步运行队列中。

Volley和OkHttp对比

都支持http请求,get、post方法。

Volley

  • 适合进行数据量不大,但通信频繁的网络操作。
  • 不适合大文件下载。
  • 可直接在主线程调用服务端并处理返回结果。

OkHttp

  • 支持https。
  • callback回来是在线程里面, 不能刷新UI,需要我们手动处理
  • 封装比较麻烦。
原创粉丝点击