[转]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请求的主要步骤。首先我们要创建一个OkHttpClickRequest.Builder()对象,再通过url()方法设置了网络地址来指定访问的目标,不仅如此 Request.Builder() 是支持链式编程的(返回体是本体)在这里可以设置这些方法哦:

Request.Builder()链式编程,在此不做探讨

接下来我们就要将OkHttpClick的对象与Request的对象建立起来联系,使用okHttpClicknewCall()方法得到一个Call对象,这个Call对象的作用就是相当于将请求封装成了一个任务,既然是任务,自然就会有execute()和cancel()等方法。

最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。但要注意的是,call的回调是子线程,所以是不能直接操作界面的。使用时需要自行处理。当请求成功时就会回调onResponse()方法,我们可以看到返回的结果是 Response对象,在此我们比较关注的是请求中的返回体bodyResponseBody类型),大多数的情况下我们希望获得字符串从而进行json解析获得数据,所以可以通过body.string()的方式获得字符串。

ResponseBody 的 API

查看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文件,还可以上传StringByteStringbyte数组等类型,其中上传byte数据时可以选择三个参数的creta方法,需要指定偏移量和需要写入的byte长度,哈哈这不是说明可以直接进行多线程、断点上传吗!通过这些类型,我们可以上传Json串,图片等内容真是方便又好用啊。

总结

经过上面的介绍我相信大家对OkHttp简单使用有了一定的了解,OkHttp3使用起来是不是很简单呢,但是每一次请求的步骤都有着大量重复的地方,这要是在实际开发中,还不把人累着啊,本着节约开(tou)发周(lan)期的目的,咳咳,后面的文章会进一步的带领大家学习OkHttp3的高级用法和OkHttp工具类的封装哦,敬请期待。

参考:

  1. https://github.com/square/okhttp
  2. Android OkHttp完全解析 是时候来了解OkHttp了

(原文地址:http://www.jianshu.com/p/7d88613c0b0f)

时间: 2024-07-29 11:45:24

[转]OkHttp3 最有营养的初级教程的相关文章

shellKali Linux Web 渗透测试— 初级教程(第三课)

shellKali Linux Web 渗透测试— 初级教程(第三课) 文/玄魂 目录 shellKali Linux Web 渗透测试—初级教程(第三课)... 1 课程目录... 1 通过google hack寻找测试目标... 2 一个asp站点的sql注入... 3 一个php站点的sql注入... 4  课程地址:点击 课程目录 两个基本案例,以sql注入入手,目标为熟悉基本的思路,关注细节信息. 关于google hack,web 扫描,sql注入更详细和复杂的内容后续教程会专门讲解

VFP+6.0中文版教程--初级教程

下载地址:网盘下载 Microsoft Visual FoxPro 6.0中文版教程 初级教程目录 第一课 开场白第二课 见识一下面向对象的编程第三课 简要介绍对象.属性.事件.方法第四课 常用的对象.属性.事件.方法第五课 常用编程命令及常用函数第六课 编一个完整的软件第七课 编程中的一些技巧第八课 程序的调试第九课 软件的编译及生成安装盘 下载地址:网盘下载

《英语语法新思维初级教程》学习笔记(二)名词

参考资料: 1. <英语语法新思维初级教程> ? 知识点 ▼ 名词是用来表示人.事物.地点以及抽象事物的名称. ▼ 名词通常分为两大类:专有名词(proper noun)和普通名词(common noun). ▼ 专有名词表示特定的人.物.机构或场所等的名词(首字母须大写).如:Paris,the United States和Bill Gates等. ▼ 普通名词又分为:可数名词(countable noun)和不可数名词(uncountable noun)两类. ▼ 可数名词 = 个体名词

《英语语法新思维初级教程》学习笔记(一)名词短语

参考资料: 1. <英语语法新思维初级教程> ? 知识点 ▼ 英语是“固定词序语言(a fixed-word-order language)”. ▼ 语言的构造级别分五个层次:1. 词(word):2. 短语(phase):3. 句子(sentence):4. 段落(paragraph):5. 篇章(discourse) a red rectangle emblazoned with five starts. ▼ 名词短语是由名词和它的修饰语一起构成的.名词的修饰语与名词的关系分两种:1. 放

chrome plug 初级教程

前言:本教程适合于有一定HTML.CSS.JS基础的前端开发人员.如何写一个chrome 插件呢?在入门时只需要弄明白以下4个概念就OK了.1.manifest.json配置文件2.background背景区3.popup弹出区4.content内容区 那么,在讲那4个概念之前,我们先来了解下chrome的文件结构.先看图 开发环境下的文件主要是放在src中,src之外的可以任意放你需要的文件夹,而我是用grunt打包的,所以有dist文件夹,data文件夹则是用来存放一些ajax调试数据.我们

《英语语法新思维初级教程》学习笔记(三)冠词

参考资料: 1. <英语语法新思维初级教程> 2. 英语国际英标表 ? 知识点 ▼ 限定词的是对名词起限定作用的各类词的总称,具体作用有限定名词所指的范围,对名词起泛指或特指.定量或或不定量等限定修饰. ▼ 冠词属于限定词(determiner),对名词起修饰作用.英语中的冠词由三个,其中两个是不定冠词a和an,一个是定冠词the(也可以认为它也是两个,同型不同音). out of the question // 不可能 out of question // 毫无疑问 ▼ the在辅音前读[ð

JavaScript强化教程——JQuery初级教程

本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程 --JQuery初级教程 第一步 下载jquery首先需要在jquery官网下载 jquery-3.0.0.js(版本和当前最新版本一致)放到自己的文件夹中第二部 引用jquery <script src="jquery-3.0.0.js"></script> 第三部 使用jquery语法写一个简单地程序 <!DOCTYPE html> <html la

Babylonjs 初级教程---微软的基于webgl的H5 3D游戏引擎

Babylon.js 页面图像库 游戏创建系统! Hi!欢迎阅读 Babylon.js 初级教程, 这是后面学习最棒的基于Javascript的网页图形库框架所需必备知识的一个基础介绍. 你想知道什么是框架么?  你可以把框架认为成 建筑里的脚手架, 它支撑你围绕它创建新东西而不必为底层细节操心. Babylon.js构造里一个复杂的系统, 让网页图形库更容易使用. 我们希望以一种非常快速的方式教给你大量的信息.  通常这里的任务都有多于一种方式达成.  我希望你自己去发现其它的方式.  根据对

Win2012R2 Hyper-V初级教程15 -- 基于Kerberos与CA证书的系统容灾(中)

二.基于CA证书的HTTPS复制 ??????? 刚刚看了一下关于基于Kerberos与CA证书的系统容灾(上)还是2017-08-31写的,到现在半年过去了,懒癌太重了,一直没有更新,从今天起将逐步更新完初级教程,希望能够有更多的博友了解并学习微软的虚拟化技术.前面我们说到了基于HTTP的复制,在内部网络的时候我们可以采用这种方法,因为本身而言内网相对安全很多,如果你是需要进行跨广域网的复制,建议你最好配置CA证书服务,通过443端口进行数据传输,以保证数据的安全性.下面我们就来说一下基于CA