今天,简单讲讲Android里如何使用OKHttp。

Android框架系列:

一.android EventBus的简单使用

二.android Glide简单使用

三.android OKHttp的基本使用详解

简单说一下学习okhttp的理由

  1. google在Android 6.0中删除了HttpClient的Api,采用的是则是okhttp
  2. 高效的使用HTTP,使应用运行更快更省流量
  3. 响应缓存数据避免重复网络请求
  4. 无缝的支持GZIP来减少数据流量
  5. 使用非常简单,请求和响应的Api具有流畅的建造和不变性,同时支持同步异步调用回调函数
  6. 如果网络出现问题,它会从常见的连接问题中恢复
  7. 如果服务器配置有多个IP地址,当第一个IP连接失败,它会尝试连接下一个IP

一,OKHttp介绍

okhttp是一个第三方类库,用于android中请求网络。

这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakCanary) 。用于替代HttpUrlConnection和Apache HttpClient(android API23 里已移除HttpClient)。

okhttp有自己的官网,官网网址:OKHttp官网

如果想了解原码可以在github上下载,地址是:https://github.com/square/okhttp

在AndroidStudio中使用不需要下载jar包,直接添加依赖即可:
compile ‘com.squareup.okhttp3:okhttp:3.4.1’

下面对以OKHttp3来详细介绍OKHttp的使用方法。

二,get请求的使用方法

使用OKHttp进行网络请求支持两种方式,一种是同步请求,一种是异步请求。下面分情况进行介绍。

1,get的同步请求

对于同步请求在请求时需要开启子线程,请求成功后需要跳转到UI线程修改UI。

在AndroidManifest.xml添加所需权限

<uses-permission android:name="android.permission.INTERNET" />

使用示例如下:

public void getDatasync(){new Thread(new Runnable() {@Overridepublic void run() {try {OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象Request request = new Request.Builder().url("http://www.baidu.com")//请求接口。如果需要传参拼接到接口后面。.build();//创建Request 对象Response response = null;response = client.newCall(request).execute();//得到Response 对象if (response.isSuccessful()) {Log.d("kwwl","response.code()=="+response.code());Log.d("kwwl","response.message()=="+response.message());Log.d("kwwl","res=="+response.body().string());//此时的代码执行在子线程,修改UI的操作请使用handler跳转到UI线程。}} catch (Exception e) {e.printStackTrace();}}}).start();
}

此时打印结果如下:
response.code()==200;
response.message()==OK;
res=={“code”:200,”message”:success};

注意事项:
1,Response.code是http响应行中的code,如果访问成功则返回200.这个不是服务器设置的,而是http协议中自带的。res中的code才是服务器设置的。注意二者的区别。
2,response.body().string()本质是输入流的读操作,所以它还是网络请求的一部分,所以这行代码必须放在子线程。
3,response.body().string()只能调用一次,在第一次时有返回值,第二次再调用时将会返回null。原因是:response.body().string()的本质是输入流的读操作,必须有服务器的输出流的写操作时客户端的读操作才能得到数据。而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,第二次将返回null。

2,get的异步请求

这种方式不用再次开启子线程,但回调方法是执行在子线程中,所以在更新UI时还要跳转到UI线程中。
使用示例如下:

private void getDataAsync() {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("http://www.baidu.com").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {if(response.isSuccessful()){//回调的方法执行在子线程。Log.d("kwwl","获取数据成功了");Log.d("kwwl","response.code()=="+response.code());Log.d("kwwl","response.body().string()=="+response.body().string());}}});
}

异步请求的打印结果与注意事项与同步请求时相同。最大的不同点就是异步请求不需要开启子线程,enqueue方法会自动将网络请求部分放入子线程中执行。

注意事项:
1,回调接口的onFailure方法和onResponse执行在子线程。
2,response.body().string()方法也必须放在子线程中。当执行这行代码得到结果后,再跳转到UI线程修改UI。

三,post请求的使用方法

Post请求也分同步和异步两种方式,同步与异步的区别和get方法类似,所以此时只讲解post异步请求的使用方法。
使用示例如下:

private void postDataWithParame() {OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体formBody.add("username","zhangsan");//传递键值对参数Request request = new Request.Builder()//创建Request 对象。.url("http://www.baidu.com").post(formBody.build())//传递请求体.build();client.newCall(request).enqueue(new Callback() {。。。});//回调方法的使用与get异步请求相同,此时略。
}

看完代码我们会发现:post请求中并没有设置请求方式为POST,回忆在get请求中也没有设置请求方式为GET,那么是怎么区分请求方式的呢?重点是Request.Builder类的post方法,在Request.Builder对象创建最初默认是get请求,所以在get请求中不需要设置请求方式,当调用post方法时把请求方式修改为POST。所以此时为POST请求。

四,POST请求传递参数的方法总结

在post请求使用方法中讲了一种传递参数的方法,就是创建表单请求体对象,然后把表单请求体对象作为post方法的参数。post请求传递参数的方法还有很多种,但都是通过post方法传递的。下面我们看一下Request.Builder类的post方法的声明:

public Builder post(RequestBody body)

由方法的声明可以看出,post方法接收的参数是RequestBody 对象,所以只要是RequestBody 类以及子类对象都可以当作参数进行传递。FormBody就是RequestBody 的一个子类对象。

1,使用FormBody传递键值对参数

这种方式用来上传String类型的键值对
使用示例如下:

private void postDataWithParame() {OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体formBody.add("username","zhangsan");//传递键值对参数Request request = new Request.Builder()//创建Request 对象。.url("http://www.baidu.com").post(formBody.build())//传递请求体.build();client.newCall(request).enqueue(new Callback() {。。。});//此处省略回调方法。
}

2,使用RequestBody传递Json或File对象

RequestBody是抽象类,故不能直接使用,但是他有静态方法create,使用这个方法可以得到RequestBody对象。

这种方式可以上传Json对象或File对象。
上传json对象使用示例如下:

OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,
String jsonStr = "{\"username\":\"lisi\",\"nickname\":\"李四\"}";//json数据.
RequestBody body = RequestBody.create(JSON, josnStr);
Request request = new Request.Builder().url("http://www.baidu.com").post(body).build();
client.newCall(request).enqueue(new Callback() {。。。});//此处省略回调方法。

上传File对象使用示例如下:

OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
MediaType fileType = MediaType.parse("File/*");//数据类型为json格式,
File file = new File("path");//file对象.
RequestBody body = RequestBody.create(fileType , file );
Request request = new Request.Builder().url("http://www.baidu.com").post(body).build();
client.newCall(request).enqueue(new Callback() {。。。});//此处省略回调方法。

3,使用MultipartBody同时传递键值对参数和File对象

这个字面意思是多重的body。我们知道FromBody传递的是字符串型的键值对,RequestBody传递的是多媒体,那么如果我们想二者都传递怎么办?此时就需要使用MultipartBody类。
使用示例如下:

OkHttpClient client = new OkHttpClient();
MultipartBody multipartBody =new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("groupId",""+groupId)//添加键值对参数.addFormDataPart("title","title").addFormDataPart("file",file.getName(),RequestBody.create(MediaType.parse("file/*"), file))//添加文件.build();
final Request request = new Request.Builder().url(URLContant.CHAT_ROOM_SUBJECT_IMAGE).post(multipartBody).build();
client.newCall(request).enqueue(new Callback() {。。。});

4,自定义RequestBody实现流的上传

在上面的分析中我们知道,只要是RequestBody类以及子类都可以作为post方法的参数,下面我们就自定义一个类,继承RequestBody,实现流的上传。
使用示例如下:
首先创建一个RequestBody类的子类对象:

RequestBody body = new RequestBody() {@Overridepublic MediaType contentType() {return null;}@Overridepublic void writeTo(BufferedSink sink) throws IOException {//重写writeTo方法FileInputStream fio= new FileInputStream(new File("fileName"));byte[] buffer = new byte[1024*8];if(fio.read(buffer) != -1){sink.write(buffer);}}
};

然后使用body对象:

 OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
Request request = new Request.Builder().url("http://www.baidu.com").post(body).build();
client.newCall(request).enqueue(new Callback() {。。。});

以上代码的与众不同就是body对象,这个body对象重写了write方法,里面有个sink对象。这个是OKio包中的输出流,有write方法。使用这个方法我们可以实现上传流的功能。

使用RequestBody上传文件时,并没有实现断点续传的功能。我可以使用这种方法结合RandomAccessFile类实现断点续传的功能。

五,设置请求头

OKHttp中设置请求头特别简单,在创建request对象时调用一个方法即可。
使用示例如下:

Request request = new Request.Builder().url("http://www.baidu.com").header("User-Agent", "OkHttp Headers.java").addHeader("token", "myToken").build();

其他部分代码略。

六,下载文件

在OKHttp中并没有提供下载文件的功能,但是在Response中可以获取流对象,有了流对象我们就可以自己实现文件的下载。代码如下:
这段代码写在回调接口CallBack的onResponse方法中:

try{InputStream  is = response.body().byteStream();//从服务器得到输入流对象long sum = 0;File dir = new File(mDestFileDir);if (!dir.exists()){dir.mkdirs();}File file = new File(dir, mdestFileName);//根据目录和文件名得到file对象FileOutputStream  fos = new FileOutputStream(file);byte[] buf = new byte[1024*8];int len = 0;while ((len = is.read(buf)) != -1){fos.write(buf, 0, len);}fos.flush();return file;}

超时设置,整个程序应使用这一个mOkHttpClient对象

public static void setTimeout() {mOkHttpClient.newBuilder().connectTimeout(10, TimeUnit.SECONDS)//10秒连接超时.writeTimeout(10, TimeUnit.SECONDS)//10m秒写入超时.readTimeout(10, TimeUnit.SECONDS)//10秒读取超时.build(); }

简单回顾一下,okhttp可以使用

private void getDataAsync() {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("http://www.baidu.com").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {if(response.isSuccessful()){//回调的方法执行在子线程。Log.d("kwwl","获取数据成功了");Log.d("kwwl","response.code()=="+response.code());Log.d("kwwl","response.body().string()=="+response.body().string());}}});
}

发生请求,同时指出Get和POST两种请求方式,结果在Callback里回调回来,记住是子线程,所以不能再回调修改UI.还有文件上传和下载也比较简单,具体的代码大家自己去看。

这里提供我学习时写的OKHttp的Demo:源码下载

android OKHttp的基本使用详解就讲完了。

就这么简单。

android OKHttp的基本使用详解相关推荐

  1. Android OkHttp使用和源码详解

    介绍 OkHttp 是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用.对于 Android App 来说,OkHttp 现在 ...

  2. Android OkHttp3简介和使用详解

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

  3. Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能

    Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...

  4. 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)

    . 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...

  5. android+发邮件,Android发送邮件的方法实例详解

    Android发送邮件的方法实例详解 时间:2021-05-20 本文实例讲述了Android发送邮件的方法.分享给大家供大家参考,具体如下: 在android手机中实现发送邮件的功能也是不可缺少的. ...

  6. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) -- TelephonyManager详解 >的1.4小节.  从TelephonyRegistry的大部分方法中:  ...

  7. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.  这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\And ...

  8. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.  在Telephony模块中,在RIL.Tracker(ServiceStateTr ...

  9. Android Gradle manifestPlaceholders 占位符详解

    Android Gradle manifestPlaceholders 占位符详解 在实际项目中,AndroidManifest里十几个地方的值是需要动态的改变(生成apk文件的时候).如果每次去改也 ...

最新文章

  1. Eclipse设置字体
  2. spring中mvc的跨域访问
  3. 阿里云发布云原生加速器,携手生态企业拥抱数字时代
  4. 【推荐软件】wingrep
  5. Linux CPU 信息查看
  6. php如何请求api,PHP如何发送GET/POST请求调用API
  7. 怎样计算一个整数的位数并把每一位上的数字保存下来
  8. 在CentOS7上使用FastDFS搭建文件服务器
  9. Python、Java 在线笔试
  10. 曲线组合图 类型详情
  11. 按键精灵 懒人插件连接mysql_按键精灵的办公插件大全下载-按键精灵懒人办公插件【新版】下载V15.0106.0.2官方免费版-西西软件下载...
  12. ecshop 源码文件结构说明
  13. 用ROS来做无人测试平台系列之国外的一些RACECAR
  14. 技术债务的高息信用卡:深入了解那些知名的端到端机器学习平台
  15. 今日头条信息流投放:今日头条怎么开户?多少钱?投放需要注意什么
  16. 欢迎进入“健康之家”:Delos推出全球首个住宅健康技术平台
  17. 将域名直接映射到网站首页(通过域名即可访问网站首页)
  18. 【耀杨的前世今生】耀杨的毕生所学——《狗叫江湖》之“葫芦给学习法”(1)
  19. 数字图像处理第二章----数字图像基础
  20. svn checkout 出现异常,E210007:Cannot negotiate authentication mechanism

热门文章

  1. hadoop2 5个环境配置文件
  2. lodash源码分析之Hash缓存
  3. IntelliJ IDEA中日志分类显示设置
  4. thinkphp htmlspecialchars_decode
  5. 在CDH上用外部Spark2.2.1安装和配置 CarbonData
  6. Errors occurred during the build. Errors running builder 'Validation' on pro
  7. Sublime Text3 3143 注册码,亲测可用!
  8. Spring Data JPA 条件查询的关键字
  9. awk、变量、运算符、if多分支
  10. chmod 命令详解