一,简介

OkHttp 是一个高效的 HTTP 客户端,具有非常多的优势:

  1. 能够高效的执行 http,数据加载速度更快,更省流量
  2. 支持 GZIP 压缩,提升速度,节省流量
  3. 缓存响应数据,避免了重复的网络请求
  4. 使用简单,支持同步阻塞调用和带回调的异步调用

OkHttp 支持 Android2.3 以上,JDK1.7 以上。

官网地址:https://square.github.io/okhttp/

github地址:https://github.com/square/okhttp

二,基本用法

添加 OkHttp 依赖

compile 'com.squareup.okhttp3:okhttp:(insert latest version)'

最新的版本号可以在官网和github上找到

1. Get 请求

使用 OkHttp 进行 Get 请求只需要四个步骤

  1. 新建 OkHttpClient对象
  2. 构造 Request 对象
  3. 将 Request 对象封装为 Call
  4. 通过 Call 来执行同步或异步请求
        String url = "http://www.xxxx.com";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get() //默认为GET请求,可以不写
.build();
final Call call = client.newCall(request);

1.1 Get 同步请求

通过 call.excute() 方法来提交同步请求,这种方式会阻塞线程,而为了避免 ANR 异常,Android3.0 之后已经不允许在主线程中访问网络了

所以 OkHttp 的同步 get 请求需要开启一个子线程:

      new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
Log.d(TAG, response.body().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();

1.2 Get 异步请求

通过 call.enqueue(Callback)方法来提交异步请求

        call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: " + e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "OnResponse: " + response.body().toString());
}
});

2. Post 请求

创建 Post 请求的方式与 Get 方法类似,只是需要增加一个步骤,构造出一个请求参数对象RequestBody ,用于携带我们需要提交的数据。(下面均以 Post 的异步请求为例,Post 同步请求只需将 call.enqueue() 替换成 call.execute() 即可)

public Builder post(RequestBody body)

Request 的 post 方法所接收的参数是 RequestBody 对象,所以只要是 RequestBody 类及其子类都可以当做参数传入。

RequestBody是一个抽象类,常用的 RequestBody 实现类有这么几种:

2.1 FormBody

FormBody是RequestBody的实现类,用于表单方式的请求

        OkHttpClient client = new OkHttpClient();
//创建表单请求参数
FormBody.Builder builder = new FormBody.Builder();
builder.add("name", "zhangsan");
builder.add("age", "18");
FormBody formBody = builder.build();
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});

2.2 RequestBody.create(...)

RequestBody 是一个抽象类,我们不能直接使用它,但是可以通过调用它的静态create方法来获取一个RequestBody对象,该方法会创建并返回一个 RequestBody 的匿名内部类实例

查看一下 RequestBody 类,发现它有这样几个 create 方法。

其中前三个方法最终调用的都是第四个方法,所以我们可以具体看一下最后两个方法的具体实现

  /** Returns a new request body that transmits {@code content}. */
public static RequestBody create(final @Nullable MediaType contentType, final byte[] content,
final int offset, final int byteCount) {
if (content == null) throw new NullPointerException("content == null");
Util.checkOffsetAndCount(content.length, offset, byteCount);
return new RequestBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return byteCount;
}
@Override public void writeTo(BufferedSink sink) throws IOException {
sink.write(content, offset, byteCount);
}
};
}
/** Returns a new request body that transmits the content of {@code file}. */
public static RequestBody create(final @Nullable MediaType contentType, final File file) {
if (file == null) throw new NullPointerException("content == null");
return new RequestBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return file.length();
}
@Override public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
};
}

这里多解释一下

Content-Type(MediaType),即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件。常见的媒体格式类型有:

  • text/html:HTML格式
  • text/pain:纯文本格式
  • image/jpeg:jpg图片格式
  • application/json:JSON数据格式
  • application/octet-stream:二进制流数据(如常见的文件下载)
  • application/x-www-form-urlencoded:form表单encType属性的默认格式,表单数据将以key/value的形式发送到服务端
  • multipart/form-data:表单上传文件的格式

使用 create 方法可以用来用于上传 String 和 File 对象,具体实现如下:

上传JSON字符串:

        OkHttpClient client = new OkHttpClient();
//指定当前请求的 contentType 为 json 数据
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String jsonStr = "{\"name\":\"zhangsan\",\"age\":\"20\"}";
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(JSON, jsonStr))
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});

上传文件:

        OkHttpClient client = new OkHttpClient();
File file = new File(filePath);
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});

2.3 使用MultipartBody同时上传多种类型数据

多文件和键值对同时上传

        OkHttpClient client = new OkHttpClient();
MultipartBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("name", "zhangsan")
.addFormDataPart("age", "20")
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build(); Request request = new Request.Builder()
.url(url)
.post(multipartBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});

3. Call 请求器

OkHttp 客户端负责接收应用程序发出的请求,并且从服务器获取响应返回给应用程序。理论听起来十分简单,但是在实践中往往会出现很多意想不到的问题。

通过配置 OkHttpClient,可以配置重写请求、重写响应、跟踪请求、重试请求等多种操作,这样一来你发送的一个简单请求可能就会变成需要发送多个请求以及接收多个响应后才能获得想要的响应。OkHttp 将这些多次的中间请求和响应任务建模成了一个 Call 对象,但是通常情况下中间请求及响应工作不会很多,令人欣慰的是,无论发生URL重定向还是因为服务器出现问题而向一个备用IP地址再次发送请求的情况,你的代码都将正常运行。

执行Call有两种方式:

  • 同步:请求和处理响应发生在同一线程。并且此线程会在响应返回之前会一直被堵塞。
  • 异步:请求和处理响应发生在不同线程。将发送请求操作发生在一个线程,并且通过回调的方式在其他线程进行处理响应。(一般在子线程发送请求,主线程处理响应)。

Calls可以在任何线程被取消。当这个Call尚未执行结束时,执行取消操作将会直接导致此Call失败!当一个Call被取消时,无论是写入请求主体或者读取响应主体的代码操作,都会抛出一个IOException异常。

OkHttp3 使用详解的更多相关文章

  1. okhttp3使用详解

    http://blog.csdn.net/itachi85/article/details/51190687

  2. 【转】Android OkHttp3简介和使用详解

    一 OKHttp简介 OKHttp是一个处理网络请求的开源项目,Android 当前最火热网络框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpC ...

  3. OkHttp3源码详解(五) okhttp连接池复用机制

    1.概述 提高网络性能优化,很重要的一点就是降低延迟和提升响应速度. 通常我们在浏览器中发起请求的时候header部分往往是这样的 keep-alive 就是浏览器和服务端之间保持长连接,这个连接是可 ...

  4. OkHttp3源码详解(一) Request类

    每一次网络请求都是一个Request,Request是对url,method,header,body的封装,也是对Http协议中请求行,请求头,实体内容的封装 public final class R ...

  5. Android OkHttp3简介和使用详解

    一 OKHttp简介 OKHttp是一个处理网络请求的开源项目,Android 当前最火热网络框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpC ...

  6. Android 网络框架之Retrofit2使用详解及从源码中解析原理

    就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题: 1 . 什么是Retrofit? Retrofit是针对于Android/Java的.基于okHttp的.一种轻量级且安全 ...

  7. 7-OKHttp使用详解,步骤挺详细的,适合初学者使用!

    OKHttp使用详解,步骤挺详细的,适合初学者使用! 一,OKHttp介绍 okhttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Squ ...

  8. Glide使用详解(一)

    一. 下载 在build.gradle中添加依赖: compile 'com.github.bumptech.glide:glide:3.7.0' 需要support-v4库的支持,如果你的项目没有s ...

  9. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

随机推荐

  1. VMware Ubuntu18.04 安装及配置笔记

    安装Ubuntu 下载虚拟机VMware 下载镜像Ubuntu 过程略, 参考 https://zhuanlan.zhihu.com/p/38797088 Ubuntu配置 特别提示: 在Ubuntu ...

  2. Vue开发——实现吸顶效果

    因为项目需求,最近开始转到微信公众号开发,接触到了Vue框架,这个效果的实现虽说是基于Vue框架下实现的,但是同样也可以借鉴到其他地方,原理都是一样的. 进入正题,先看下效果图: 其实js做这个效果还 ...

  3. vue改变数据视图刷新问题

    有时候我们会碰到数据已经更新了但是视图不更新的问题 1.根属性不存在,而想要直接给根属性赋值导致的视图不更新 解决:初始化属性的时候给根属性初始化一个空值就可以了 2.数组视图不更新 通过以下几个方法 ...

  4. 解决跨域问题,前端 live-server --port=1802 后端启动 localhost:1801,以及解决 vue 的 axios 请求整合

    测试的源码文件内容点击跳转 前端引入 vue.js 与 axios.min.js <script src="https://cdn.bootcss.com/vue/2.6.10/vue ...

  5. 使用pagehelper分页工具page警告问题

    警告: Hessian/Burlap: 'com.github.pagehelper.Page' is an unknown class in WebappClassLoader java.lang. ...

  6. Get To Know Linux: The /etc/init.d Directory

    If you use Linux you most likely have heard of the init.d directory. But what exactly does this dire ...

  7. 08 自学Aruba之限制应用流量

    点击返回:自学Aruba之路点击返回:自学Aruba集锦 08 自学Aruba之限制应用流量 限制带宽请查阅:点击 下文描述的步骤,主要是针对某一个SSID所用用户在使用某一个应用的时候设置共享带宽. ...

  8. windows调试之命令行窗口问题

    CProProcess::InitProProcess(_T("safeProcessDemo")); cout << "Enter 'q' to exit: ...

  9. springboot jpa 创建数据库以及rabbitMQ分模块扫描问题

    在使用jpa过程中,如果没有在配置中加入自动创建实体对于的sql,则需要提前创建建表语句 spring.jpa.properties.hibernate.show_sql=true spring.jp ...

  10. Gym - 101170B British Menu (强连通缩点+dp)

    题意:求一个有向图上的最长路(每个强连通分量的点不超过5个) 首先对强连通分量缩点,暴力预处理出len[k][i][j]表示第k个强连通分量里的第i个点和第j个点之间的最长路径,设状态(k,i,f)表 ...