在导入okhttp的时候还在想,为什么还是okhttp2.x呢?怎么还不更新呢?然后网上一搜才知道,人家早就升级了好吗?人家已经换名字了好吗?人家别人的教程都一大堆了好吗?,好吧,我承认,我不是一个紧跟潮流的人,,,
所以今天我主要是记录一下我对okhttp3的学习,需要说的一点是这个是我的学习笔记,所以有的地方和链接的博客有很多相似的地方,所以请你不要说我写这个有什么意义,好吗?
好了,正文开始,,,
导入我们需要使用的库
compile 'com.squareup.okhttp3:okhttp:3.4.0-RC1'
这个时候我们就需要创建一个OkHttpClient实例了
OkHttpClient是一个可以发送http请求并读取该http请求的响应,是一个生产call的工厂。
受益于一个共享的响应缓存/线程池/复用的连接等因素,绝大多数应用使用一个OkHttpClient实例就可以了。
创建OkHttpClient实例
使用默认的构造函数,即:
OkHttpClient mOkHttpClient=new OkHttpClient();
通过
new OkHttpClient.Builder()
一步一步配置OkHttpClient mOkHttpClient=new OkHttpClient.Build().build();//在build()之前我们可以设置缓存,连接时间等
如果要求使用现有的实例,可以通过
newBuilder()
方法来进行构造OkHttpClient client=... OkHttpClient clientWith30sTimeout=client.newBuilder() .readTimeout(30,TimeUnit.SECONDS) .build();
需要注意的是:
第一种创建方式是okhttp3之前的创建方式,在okhttp3中提供了第二种创建方式,很好的使用了创建者的设计模式,但是第一种在okhttp3中也可以使用,但是呢,我还是比较推荐第二种,嘿嘿
接下来,我们就可以写我们的网络请求了
通常我们会先创建一个Request,代码通常如下:
Request request = new Request.Builder() //.header("User-Agent","OkHttp Headers.java") //.addHeader("Accept","application/json;q=0.5") //.addHeader("Accept","application/vnd.github.v3+json") .url(url) .tag(tag) .build();
Request代表的是一个Http请求,一旦build之后,就不可以修改了。
可以看到我们在这里设置了一个tag值,这个值的作用是用于取消网络请求的,具体会在下边有介绍。
在这里我们通常也会指定头信息。指定头信息的方法一般有两种,第一种是直接使用header(name,value)方法,一种是使用addHeader(name.value)方法(上边注释掉的即为添加头信息的方法)。两种方法的区别如下:
- header(name,value)
可以设置唯一的name,value。如果已经有值,旧的将被移除,然后添加新的。
- addHeader(name,value)
可以添加多值,如果请求头中已经存在name的name-value,那么使用此方法还会继续添加,请求头中便会存在多个name相同而value不同的键值对。
然后我们就会执行这个请求了
mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });
可以看到我们使用mOkHttpClient和request一起构造了一个realCall实例,realCall简单做了一个托管并通过`Dispather`类对请求进行了分发和执行(开启线程发起请求的方法就是在这个类)。因为我这写的是异步操作,如果想要修改UI的东西,还需要我们回到主线程。
有的时候我们还会遇到取消请求的状况,例如说还没有请求完成,用户就按了home键回到主页面,在okhttp2中我们可以给call设置一个tag,然后直接执行取消即可,可是在okHttp3中并没有这个方法,所以我们就用到了刚刚在Request中设置的tag值,具体的代码如下(这是在Issues2205中提到的)
public void cancle(HttpClient client,String tag) { for (Call call : client.dispatcher().queuedCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } for (Call call : client.dispatcher().runningCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } }