[转]OkHttp3 最有营养的初级教程
一、前言
自从Android4.4开始,google已经开始将源码中的HttpURLConnection替换为OkHttp,而在Android6.0之后的SDK中google更是移除了对于HttpClient的支持,而市面上流行的Retrofit同样是使用OkHttp进行再次封装而来的。由此看见学习OkHttp的重要性。
本篇文章是以当前最新的版本 3.5.0为例(2.0及以上版本版本与3.0以上版本存在较大差异,本文不做深入讨论,请自行百度),使用Android Stuido作为开发环境,带领大家简单的熟悉OKHttp的使用情况。作为《Android网络编程》系类文章之一,后面的文章会围绕OKHttp3做逐渐深入的探讨。这篇文章我们要达到的目的就是:不深究,简单明了,可以直接粘贴复制。
二、使用前的准备
2.1 官方文档
要知道学习一门新技术,最好的资料永远是官方文档:
OkHttp官方介绍
github源码
2.2 Android Studio 配置gradle环境:
compile 'com.squareup.okhttp3:okhttp:3.5.0'
compile 'com.squareup.okio:okio:1.11.0'
2.3 添加网络权限
不要忘记添加权限啊,这也是常常被开发忽略的地方
<uses-permission android:name="android.permission.INTERNET"/>
三、使用教程
3.1 Http Get
3.1.1 异步的Get
在Http请求中最常见的就是get方法了,在大多数的使用场景中,我们使用的都是异步的Get请求,下面我们就是用OkHttp的异步Get去请求一下百度的首页。
// step 1: 创建 OkHttpClient 对象
OkHttpClient okHttpClient = new OkHttpClient();
// step 2: 创建一个请求,不指定请求方法时默认是GET。
Request.Builder requestBuilder = new Request.Builder().url("http://www.baidu.com");
//可以省略,默认是GET请求
requestBuilder.method("GET",null);
// step 3:创建 Call 对象
Call call = okHttpClient.newCall(requestBuilder.build());
//step 4: 开始异步请求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// TODO: 17-1-4 请求失败
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// TODO: 17-1-4 请求成功
//获得返回体
ResponseBody body = response.body();
}
});
以上就是发送一个异步的Get请求的主要步骤。首先我们要创建一个OkHttpClick
和Request.Builder()
对象,再通过url()
方法设置了网络地址来指定访问的目标,不仅如此 Request.Builder()
是支持链式编程的(返回体是本体)在这里可以设置这些方法哦:
接下来我们就要将OkHttpClick
的对象与Request
的对象建立起来联系,使用okHttpClick
的newCall()
方法得到一个Call
对象,这个Call对象的作用就是相当于将请求封装成了一个任务,既然是任务,自然就会有execute()和cancel()等方法。
最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。但要注意的是,call的回调是子线程,所以是不能直接操作界面的。使用时需要自行处理。当请求成功时就会回调onResponse()
方法,我们可以看到返回的结果是 Response
对象,在此我们比较关注的是请求中的返回体body
(ResponseBody
类型),大多数的情况下我们希望获得字符串从而进行json解析获得数据,所以可以通过body.string()
的方式获得字符串。
查看ResponseBody
的API文档可以看到,body
还可以获取byte[]、Reader、InputStream,其中最惊奇一点就是可以返回InputStream,这至少说明了OkHttp是可以支持大文件的下载的,这样一来我们就可以轻松的使用InputStream进行I/O方式的文件写入啦!!!。
让我们实现一下吧:
//step 1: 不变的第一步创建 OkHttpClick
OkHttpClient okHttpClient = new OkHttpClient();
//step 2: 创建Requset
Request request = new Request.Builder()
.url("http://www.ssyer.com/uploads/org_2017010593503_775.jpg")
.build();
//step 3:建立联系,创建Call
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) {
InputStream inputStream = response.body().byteStream();
FileOutputStream fileOutputStream = null;
try {
File file = new File(Environment.getExternalStorageDirectory() + "大狮子.jpg");
fileOutputStream = new FileOutputStream(file);
byte[] buffer = new byte[2048];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("downloadAsynFile", "文件下载成功");
}
});
3.1.1 同步的Get
当然Get
也支持阻塞方式的同步请求,不过在开发中这种方法很少被使用。上面我们也说了Call有一个execute()
方法,你也可以直接调用call.execute()
返回一个Response
。然后利用isSuccessful()
判读是否成功,进行相应的结果解析。
3.2 异步的Http Post
在看过了Get
请求方式,相信你对于请求的用法也用基本的掌握了,Post
的使用使用方法和Get
虽然存在些许差异,但是本质是不变的。那么下面就让我们以携带键值对的Post
为例,先熟悉一下Post
的使用方法吧。
3.2.1 Post 上传键值对
//step 1: 同样的需要创建一个OkHttpClick对象
OkHttpClient okHttpClient = new OkHttpClient();
//step 2: 创建 FormBody.Builder
FormBody formBody = new FormBody.Builder()
.add("name", "dsd")
.build();
//step 3: 创建请求
Request request = new Request.Builder().url("http://www.baidu.com")
.post(formBody)
.build();
//step 4: 建立联系 创建Call对象
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// TODO: 17-1-4 请求失败
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// TODO: 17-1-4 请求成功
}
});
是不是和Get
很相似啊。大家都清楚,在使用Post
的时候,参数是包含在请求体中的。所以我们通过FormBody
,添加多个String键值对,然后为Request
添加post(formBody)
完成我们Request
的构造。之后的步骤就和Get的步骤一样了,是不是很简单啊!
3.2.2 Post异步上传文件
直接上代码
// step 1: 创建 OkHttpClient 对象
OkHttpClient okHttpClient = new OkHttpClient();
//step 2:创建 RequestBody 以及所需的参数
//2.1 获取文件
File file = new File(Environment.getExternalStorageDirectory() + "test.txt");
//2.2 创建 MediaType 设置上传文件类型
MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");
//2.3 获取请求体
RequestBody requestBody = RequestBody.create(MEDIATYPE, file);
//step 3:创建请求
Request request = new Request.Builder().url("http://www.baidu.com")
.post(requestBody)
.build();
//step 4 建立联系
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// TODO: 17-1-4 请求失败
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// TODO: 17-1-4 请求成功
}
});
当然这里需要添加权限滴,你是不是忘记了呢。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
第一步与之前都相同,但是从第二步开始就用了一定的差异了。在step2 中我们需要通过MediaType.parse("text/plain; charset=utf-8")
为上传文件设置一定类型(MIME)在这里我们上传的纯文本文件所以选择"text/plain
类型,而编码格式为utf-8
。下面为大家列出常见的文件类型,方便使用。
参数 | 说明 |
---|---|
text/html | HTML格式 |
text/plain | 纯文本格式 |
text/xml | XML格式 |
image/gif | gif图片格式 |
image/jpeg | jpg图片格式 |
image/png | png图片格式 |
application/xhtml+xml | XHTML格式 |
application/xml | XML数据格式 |
application/atom+xml | Atom XML聚合格式 |
application/json | JSON数据格式 |
application/pdf | pdf格式 |
application/msword | Word文档格式 |
application/octet-stream | 二进制流数据 |
其实MIME文件类型特批多,有兴趣的朋友可以可参见w3school上的MIME 参考手册。
在创建RequestBody
的时候可以看到,我们不仅仅可以上传File文件,还可以上传String
,ByteString
,byte
数组等类型,其中上传byte数据时可以选择三个参数的creta方法,需要指定偏移量和需要写入的byte长度,哈哈这不是说明可以直接进行多线程、断点上传吗!通过这些类型,我们可以上传Json串,图片等内容真是方便又好用啊。
总结
经过上面的介绍我相信大家对OkHttp简单使用有了一定的了解,OkHttp3使用起来是不是很简单呢,但是每一次请求的步骤都有着大量重复的地方,这要是在实际开发中,还不把人累着啊,本着节约开(tou)发周(lan)期的目的,咳咳,后面的文章会进一步的带领大家学习OkHttp3的高级用法和OkHttp工具类的封装哦,敬请期待。
参考:
(原文地址:http://www.jianshu.com/p/7d88613c0b0f)
[转]OkHttp3 最有营养的初级教程的更多相关文章
- Python图像处理库:Pillow 初级教程
Python图像处理库:Pillow 初级教程 2014-09-14 翻译 http://pillow.readthedocs.org/en/latest/handbook/tutorial.html ...
- shellKali Linux Web 渗透测试— 初级教程(第三课)
shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课) 课程目录 通过google hack寻找测 ...
- Mac OS X Terminal 101:终端使用初级教程
Mac OS X Terminal 101:终端使用初级教程 发表于 2012 年 7 月 29 日 由 Renfei Song | 文章目录 1 为什么要使用命令行/如何开启命令行? 2 初识Com ...
- Coding 初级教程(二)——上传已有项目
Coding 初级教程(二)——上传已有项目 [摘要:方针读者 :已具有 Coding.net 的账号. 本文首要先容若何把项目上传到 Coding.net 上. 分两种环境,一种是项目已归入到 gi ...
- [初级教程]用SecureCRT+Xming轻松远程实现Linux的X DISPLAY
[初级教程]用SecureCRT+Xming轻松远程实现Linux的X DISPLAY 发布者:sqqdugdu 时间:10-06 阅读数:2117 测试环境:RHEL 6.1,SecureCRT 5 ...
- Window服务初级教程以及log4net配置文件初始化
Window服务初级教程:http://www.jb51.net/article/48987.htm 另外,配置log4net这个日志功能的时候需要初始化,不然会报没有初始化的错误,而且初始化的节点应 ...
- 《自学C语言》初级教程 - 目录
我现在打算出一个C语言学习教程,目的是为了让初学者能够很容易和更深刻地理解C语言. 你可能有这样的疑问,网上不是有很多的初级教程吗,我需要这个吗?我的回答是:网上的C语言教程讲得不够全面,而且许多的初 ...
- Android初级教程理论知识(第三章测试&数据存储&界面展现)
首先介绍单元测试,我在javaweb部分有详细介绍单元测试框架的一篇文章. 可以先看在javaweb中的单元测试详解篇http://blog.csdn.net/qq_32059827/article/ ...
- Apache Solr 初级教程(介绍、安装部署、Java接口、中文分词)
Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...
随机推荐
- Linux Centos7中MySql安装
(1) 安装Mysql5.7: 执行命令:rpm -ivh http://repo.mysql.com/yum/mysql-5.7-community/el/7/x86_64/mysql-co ...
- JERSEY中文翻译(第三章、模块和依赖)
Chapter 2 Modules and Dependencencies 2.1 Java SE 兼容 所有的Jersey组建都是基于Java6开发的,所以你的Java必须是Java6以上的版本才能 ...
- angularjs显示html片段
ngBindHtml <div ng-controller="ExampleController"> <p ng-bind-html="myHTML&q ...
- 【Linux 驱动】Netfilter/iptables (八) Netfilter的NAT机制
NAT是Network Address Translation的缩写,意即"网络地址转换". 从本质上来说,是通过改动IP数据首部中的地址,以实现将一个地址转换成还有一个地址的技术 ...
- css 进度条
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- Ant脚本简介与基础知识
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6624003.html 一:Ant是什么 Ant相当于Linux环境下的shell脚本,只不过是用xml文档来 ...
- 【Fanvas技术解密】HTML5 canvas实现脏区重绘
先说明一下,fanvas是笔者在企鹅公司开发的,即将开源的flash转canvas工具. 脏区重绘(dirty rectangle)并不是一门新鲜的技术了,这在最早2D游戏诞生的时候就已经存在. 复杂 ...
- golang 垃圾回收机制
用任何带 GC 的语言最后都要直面 GC 问题.在以前学习 C# 的时候就被迫读了一大堆 .NET Garbage Collection 的文档.最近也学习了一番 golang 的垃圾回收机制,在这里 ...
- oracle 快速复制表结构、表数据
1.情景展示 根据现有的表,建一个新的表,要求:新表的结构与原有表的表结构一模一样,如何快速实现? 根据现有的表,建一个新的表,要求:新表的结构.数据与原表一模一样,如何实现快速复制旧表? 2.解 ...
- ROS中发布激光扫描消息
激光雷达工作时会先在当前位置发出激光并接收反射光束,解析得到距离信息,而后激光发射器会转过一个角度分辨率对应的角度再次重复这个过程.限于物理及机械方面的限制,激光雷达通常会有一部分“盲区”.使用激光雷 ...