转载请标明出处: 
http://blog.csdn.net/lmj623565791/article/details/49734867; 
本文出自:【张鸿洋的博客】

一、概述

之前写了篇Android OkHttp完全解析 是时候来了解OkHttp了,其实主要是作为okhttp的普及文章,当然里面也简单封装了工具类,没想到关注和使用的人还挺多的,由于这股热情,该工具类中的方法也是剧增,各种重载方法,以致于使用起来极不方便,实在惭愧。

于是,在这个周末,抽点时间对该工具类,进行了重新的拆解与编写,顺便完善下功能,尽可能的提升其使用起来的方便性和易扩展性。

标题的改善,也是指的是对于我之前的代码进行改善。

如果你对okhttp不了解,可以通过Android OkHttp完全解析 是时候来了解OkHttp了进行了解。

ok,那么目前,该封装库志支持:

  • 一般的get请求
  • 一般的post请求
  • 基于Http的文件上传
  • 文件下载
  • 上传下载的进度回调
  • 加载图片
  • 支持请求回调,直接返回对象、对象集合
  • 支持session的保持
  • 支持自签名网站https的访问,提供方法设置下证书就行
  • 支持取消某个请求

源码地址:https://github.com/hongyangAndroid/okhttp-utils


引入:

  • Android Studio

    使用前,对于Android Studio的用户,可以选择添加:

    compile project(':okhttputils')
    • 1
    • 1

    或者

    compile 'com.zhy:okhttputils:2.0.0'
    • 1
    • 1
  • Eclipse

    自行copy源码。

二、基本用法

目前基本的用法格式为:

OkHttpUtils.get().url(url).addParams("username", "hyman").addParams("password", "123").build().execute(callback);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

通过链式去根据自己的需要添加各种参数,最后调用execute(callback)进行执行,传入callback则代表是异步。如果单纯的execute()则代表同步的方法调用。

可以看到,取消了之前一堆的get重载方法,参数也可以进行灵活的选择了。

下面简单看一下,全部的用法:

(1)GET请求

String url = "http://www.csdn.net/";
OkHttpUtils.get().url(url).addParams("username", "hyman").addParams("password", "123").build().execute(new StringCallback(){@Overridepublic void onError(Request request, Exception e){}@Overridepublic void onResponse(String response){}});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

(2)POST请求

 OkHttpUtils.post().url(url).addParams("username", "hyman").addParams("password", "123").build().execute(callback);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(3)Post String

OkHttpUtils.postString().url(url).content(new Gson().toJson(new User("zhy", "123"))).build().execute(new MyStringCallback());   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

将string作为请求体传入到服务端,例如json字符串。

(4)Post File

OkHttpUtils.postFile().url(url).file(file).build().execute(new MyStringCallback());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

将file作为请求体传入到服务端.

(5)基于POST的文件上传(类似web上的表单)

OkHttpUtils.post()//.addFile("mFile", "messenger_01.png", file)//.addFile("mFile", "test1.txt", file2)//.url(url).params(params)//.headers(headers)//.build()//.execute(new MyStringCallback());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(6)下载文件

OkHttpUtils//.get()//.url(url)//.build()//.execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "gson-2.2.1.jar")//{@Overridepublic void inProgress(float progress){mProgressBar.setProgress((int) (100 * progress));}@Overridepublic void onError(Request request, Exception e){Log.e(TAG, "onError :" + e.getMessage());}@Overridepublic void onResponse(File file){Log.e(TAG, "onResponse :" + file.getAbsolutePath());}});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

(7)显示图片

OkHttpUtils.get()//.url(url)//.build()//.execute(new BitmapCallback(){@Overridepublic void onError(Request request, Exception e){mTv.setText("onError:" + e.getMessage());}@Overridepublic void onResponse(Bitmap bitmap){mImageView.setImageBitmap(bitmap);}});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

哈,目前来看,清晰多了。

三、对于上传下载的回调

new Callback<?>()
{//...@Overridepublic void inProgress(float progress){//use progress: 0 ~ 1}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

对于传入的callback有个inProgress方法,需要拿到进度直接复写该方法即可。

四、对于自动解析为实体类

目前去除了Gson的依赖,提供了自定义Callback的方式,让用户自己去解析返回的数据,目前提供了StringCallbackFileCallback,BitmapCallback 分别用于返回string,文件下载,加载图片。

当然如果你希望解析为对象,你可以:

public abstract class UserCallback extends Callback<User>
{//非UI线程,支持任何耗时操作@Overridepublic User parseNetworkResponse(Response response) throws IOException{String string = response.body().string();User user = new Gson().fromJson(string, User.class);return user;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

自己使用自己喜欢的Json解析库完成即可。

解析成List<User>,则如下:

public abstract class ListUserCallback extends Callback<List<User>>
{@Overridepublic List<User> parseNetworkResponse(Response response) throws IOException{String string = response.body().string();List<User> user = new Gson().fromJson(string, List.class);return user;}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

五、对于https单向认证

非常简单,拿到xxx.cert的证书。

然后调用


OkHttpUtils.getInstance().setCertificates(inputstream);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

建议使用方式,例如我的证书放在assets目录:


/*** Created by zhy on 15/8/25.*/
public class MyApplication extends Application
{@Overridepublic void onCreate(){super.onCreate();try{    OkHttpUtils.getInstance().setCertificates(getAssets().open("aaa.cer"),getAssets().open("server.cer"));} catch (IOException e){e.printStackTrace();}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

即可。别忘了注册Application。

注意:如果https网站为权威机构颁发的证书,不需要以上设置。自签名的证书才需要。

六、配置

(1)全局配置

可以在Application中,通过:

OkHttpClient client =
OkHttpUtils.getInstance().getOkHttpClient();
  • 1
  • 2
  • 1
  • 2

然后调用client的各种set方法。

例如:

client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);
  • 1
  • 1

(2)为单个请求设置超时

比如涉及到文件的需要设置读写等待时间多一点。

 OkHttpUtils.get()//.url(url)//.tag(this)//.build()//.connTimeOut(20000).readTimeOut(20000).writeTimeOut(20000).execute()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

调用build()之后,可以随即设置各种timeOut.

(3)取消单个请求

 RequestCall call = OkHttpUtils.get().url(url).build();call.cancel();
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

(4)根据tag取消请求

目前对于支持的方法都添加了最后一个参数Object tag,取消则通过OkHttpUtils.cancelTag(tag)执行。

例如:在Activity中,当Activity销毁取消请求:

OkHttpUtils.get()//.url(url)//.tag(this)//.build()//@Override
protected void onDestroy()
{super.onDestroy();//可以取消同一个tag的OkHttpUtils.cancelTag(this);//取消以Activity.this作为tag的请求
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

比如,当前Activity页面所有的请求以Activity对象作为tag,可以在onDestory里面统一取消。

七、浅谈封装

其实整个封装的过程比较简单,这里简单描述下,对于okhttp一个请求的流程大致是这样的:

//创建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(new Callback()
{@Overridepublic void onFailure(Request request, IOException e){}@Overridepublic void onResponse(final Response response) throws IOException{//String htmlStr =  response.body().string();}
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

其中主要的差异,其实就是request的构建过程。

我对Request抽象了一个类:OkHttpRequest

public abstract class OkHttpRequest
{protected RequestBody requestBody;protected Request request;protected String url;protected String tag;protected Map<String, String> params;protected Map<String, String> headers;protected OkHttpRequest(String url, String tag,Map<String, String> params, Map<String, String> headers){this.url = url;this.tag = tag;this.params = params;this.headers = headers;}protected abstract Request buildRequest();protected abstract RequestBody buildRequestBody();protected void prepareInvoked(ResultCallback callback){requestBody = buildRequestBody();requestBody = wrapRequestBody(requestBody, callback);request = buildRequest();}protected RequestBody wrapRequestBody(RequestBody requestBody, final ResultCallback callback){return requestBody;}public void invokeAsyn(ResultCallback callback){prepareInvoked(callback);mOkHttpClientManager.execute(request, callback);}// other common methods}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

一个request的构建呢,我分三个步骤:buildRequestBody , wrapRequestBody ,buildRequest这样的次序,当以上三个方法没有问题时,我们就拿到了request,然后执行即可。

但是对于不同的请求,requestBody以及request的构建过程是不同的,所以大家可以看到buildRequestBody ,buildRequest为抽象的方法,也就是不同的请求类,比如OkHttpGetRequestOkHttpPostRequest等需要自己去构建自己的request。

对于wrapRequestBody方法呢,可以看到它默认基本属于空实现,主要是因为并非所有的请求类都需要复写它,只有上传的时候呢,需要回调进度,需要对requestBody进行包装,所以这个方法类似于一个钩子。

其实这个过程有点类似模板方法模式,有兴趣可以看看一个短篇介绍设计模式 模版方法模式 展现程序员的一天 .

对于更加详细的用法,可以查看github上面的readme,以及demo,目前demo包含:

对于上传文件的两个按钮,需要自己搭建服务器,其他的按钮可以直接测试。

最后,由于本人水平有限,以及时间比较仓促~~发现问题,欢迎提issue,我会抽时间解决。 have a nice day ~

源码点击下载

Android 一个改善的okHttp封装库相关推荐

  1. Android okHttp封装库(2) -- okhttp-OkGo

    OkGo - OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持RxJava 该库是封装了okhttp的标准RESTful风格的网络框架,可以与RxJava完美结合,比Retrof ...

  2. Android客户端连接服务器- OKHttp的简单实用方法

    文章目录 一 .OKHttp简介 二. OkHttp3使用 1.创建HTTPClient实例 2.Get请求 3.POST请求 三.Timeouts(超时) **写在前面:本文只是对OKHttp3的简 ...

  3. android开发常用组件和第三方库(二)

    TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending, github搜索:https://github.com ...

  4. Android好用的第三方开源库

    记录一些对工作学习有帮助的第三方开源库 快捷入口 音频类 AudioPlay Banner类 banner 流式布局 FlowLayout 网络请求框架 RxEasyHttp okhttp-RxHtt ...

  5. 建立自己的封装库(一)

    经常会遇到需要自己画封装的情况,之前每次都是一个原件新建一个原理图库和pcb库,而且有没有联系起来,时间长了会发现很乱,而且也会养成不好的习惯,后来在网上找过很多资料,建立了一个属于自己的封装库,方便 ...

  6. 打造Altium Designer 3D封装库

    看到Andy_2020发的帖子"Altium Designer专题"之后,对Altium Designer的3D功能很感兴趣,着手自己做一个AD的3D封装库.刚开始按照Andy介绍 ...

  7. NFC芯片NT3H1101W0FHKH封装库以及手册

    自己画的一个NFC芯片的封装库 顺便附上手册! https://github.com/1106525618/NFC

  8. Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

  9. Android之全面解析Retrofit网络框架封装库

    转载请标明出处:[顾林海的博客] 前言 Retrofit是Square公司推出的一个HTTP的框架,主要用于Android和Java,Retrofit会将每一个HTTP的API请求变成一个Java的接 ...

最新文章

  1. C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员
  2. Gh0st源码学习(三)生成DLL和DAT文件
  3. vue 3.0 正式版_Vuejs 3 Release:One Piece. Vuejs 3.0 正式版发布!代号:海贼王
  4. ManualResetEvent详解
  5. 【并查集】noi2001食物链
  6. 支持FreeMarker需要哪些JAR包?
  7. c语言调用sqlite
  8. Oracle学习总结(6)—— SQL注入技术
  9. 搭建LINUX BIND实现DNS解析
  10. Kubernetes 1.5安装
  11. 不能错过的linux驱动开发的经典书籍推荐
  12. 关于ISO27001信息安全管理体系的内容详细概括
  13. 支付宝、京东支付场景之策略模式实战
  14. 如何利用RFM模型对客户进行精细化管理
  15. 基于Matlab高斯光束前向与后向传播的模拟
  16. 诺基亚5320XM 上的最好的手机浏览器,UCWEB 6
  17. ai面试的优缺点_AI面试需要注意哪些问题?
  18. C语言的程序设计流程、特点及要求
  19. 部门换届推文文字_宿委会换届表彰大会!!!
  20. symfony简单的博客练习,熟悉具体开发流程

热门文章

  1. nyoj-1016-德莱联盟(向量叉乘判断线段相交)
  2. 「Adobe国际认证」Adobe Photoshop,如何裁剪并拉直照片?
  3. uni-app在App平台如何实现升级更新?
  4. 赴日工作之在留换签证
  5. hellow world
  6. Windows的sc命令详解
  7. 如何知道您是否准备从Mac切换到Linux
  8. 多目标优化算法:多目标非洲秃鹫优化算法MOAVOA(提供Matlab代码)
  9. 【算法】01背包及其优化详解
  10. Apache服务器配置参数的全面说明(所有参数)