OKhttp初步学习

简介

OkHttp是一个专注于性能和易用性的 HTTP 客户端(是一个高效的HTTP库),用来发送 HTTP 请求并对所得到的响应进行处理。非常高效,支持SPDY、连接池、GZIP和 HTTP 缓存。

  • 支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求
  • 如果SPDY不可用,则通过连接池来减少请求延时
  • 无缝的支持GZIP来减少数据流量
  • 缓存响应数据来减少重复的网络请求

我们一般经常用的功能:

  • 一般的get请求
  • 一般的post请求
  • 基于Http的文件上传
  • 文件下载
  • 加载图片

对以上功能的封装请见参考。
网络操作OKhttp配合Volley、Gson食用味道更佳。

使用

添加依赖

AS:compile 'com.squareup.okhttp3:okhttp:3.3.1'
以上,可以在github上找到,见参考。

关于GET提交方式

设置get请求

1、调用Request.builder 对象的get()方法来设置请求方法为”get”请求。
2、调用Request.builder 对象的method(“GET”, null)方法来设置请求方法为“get”请求。

注意:method中的第二个参数表示是请求体,因为get请求的请求参数可以直接跟在url后面,所以中get请求的时候可以传递null。

同步加载(测试一直ANR)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
//阻塞式方式 会阻塞UI线程
//调用call对象的execute方法,发出网络请求,获取Response对象。
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException(Unexpected code + response);

//调用response的body方法方法获取相应体。
ResponseBody body = response.body();
//调用ResponseBody的相应方法获取具体响应内容。
body.string(); //如果结果为字符类型,调用这个方法,默认编码utf-8
body.bytes(); //返回字节数组
body.byteStream(); //返回字节输入流。
}

异步加载(官方推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//请求加入调度
//call.enqueue会开启一个新的线程
call.enqueue(new Callback()
{
//响应失败回调
@Override
public void onFailure(Request request, IOException e)
{
}
//响应成功回调
@Override
public void onResponse(final Response response) throws IOException
{
//String htmlStr = response.body().string();
}
});

以上就是发送一个get请求的步骤,首先构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:header、method等。

然后通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。

最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。

看到这,你会发现,整体的写法还是比较长的,所以封装肯定是要做的,不然每个请求这么写,得累死。

需要注意几点:

  • onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()
  • 竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //操作UI
    public void onResponse(final Response response) throws IOException {
    final String res = response.body().string();
    runOnUiThread(new Runnable(){
    @Override
    public void run(){
    mTv.setText(res);
    }
    });
    }

关于post提交方式

设置post方式

1、调用Request.builder 对象的post(requestBody)方法来设置请求方法。
2、调用Request.builder 对象的method(“POST”, requestBody)方法来设置。

注意:
1、post的请求参数(请求体requestBody)必须有,不能为null。如果为null会抛异常。
2、关于RequestBody:
RequestBody是个抽象类。

1
2
3
4
5
//使用RequestBody提交键值对:
RequestBody body = new FormEncodingBuilder()
.add("name","zs")
.add("pwd", "aaa")
.build();

进行post提交

  • 提交键值对

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    OkHttpClient client = new OkHttpClient();
    String post(String url, String json) throws IOException {

    RequestBody formBody = new FormEncodingBuilder()
    .add("platform", "android")
    .add("name", "bug")
    .add("subject", "XXXXXXXXXXXXXXX")
    .build();

    Request request = new Request.Builder()
    .url(url)
    .post(body)
    .build();

    Response response = client.newCall(request).execute();
    if (response.isSuccessful()) {
    return response.body().string();
    } else {
    throw new IOException("Unexpected code " + response);
    }
    }
  • 提交json数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //设置为json数据类型
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    OkHttpClient client = new OkHttpClient();
    String post(String url, String json) throws IOException {
    //参数--->类型和数据
    RequestBody body = RequestBody.create(JSON, json);
    Request request = new Request.Builder()
    .url(url)
    .post(body)
    .build();
    Response response = client.newCall(request).execute();
    if (response.isSuccessful()) {
    return response.body().string();
    } else {
    throw new IOException("Unexpected code " + response);
    }
    }

post的时候,参数是包含在请求体中的;所以我们通过FormEncodingBuilder。添加多个String键值对,然后去构造RequestBody,最后完成我们Request的构造。
后面的就和上面一样了。

文件和表单的的提交

暂未学习,见参考。
挖坑。

其他

  • OkHttp官方文档并不建议我们创建多个OkHttpClient,因此全局使用一个。 如果有需要,可以使用clone方法,再进行自定义。
  • OKhttp与Volley

    Volley是针对数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。如果开发中使用HttpUrlConnection则要从头开始封装对应得操作,所以最近转向了一个第三方网络请求框架OkHttp库。

参考

OKhttp的github开源库
官方API
OKhttp完整的封装类
详解OKhttp
OkHttp使用详解
OKhttp完全解析

喜欢就请我吃包辣条吧!

评论框加载失败,无法访问 Disqus

你可能需要魔法上网~~