Android 一个改善的okHttp封装库
转载请标明出处:
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的方式,让用户自己去解析返回的数据,目前提供了StringCallback
,FileCallback
,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
为抽象的方法,也就是不同的请求类,比如OkHttpGetRequest
、OkHttpPostRequest
等需要自己去构建自己的request。
对于wrapRequestBody
方法呢,可以看到它默认基本属于空实现,主要是因为并非所有的请求类都需要复写它,只有上传的时候呢,需要回调进度,需要对requestBody进行包装,所以这个方法类似于一个钩子。
其实这个过程有点类似模板方法模式,有兴趣可以看看一个短篇介绍设计模式 模版方法模式 展现程序员的一天 .
对于更加详细的用法,可以查看github上面的readme,以及demo,目前demo包含:
对于上传文件的两个按钮,需要自己搭建服务器,其他的按钮可以直接测试。
最后,由于本人水平有限,以及时间比较仓促~~发现问题,欢迎提issue,我会抽时间解决。 have a nice day ~
源码点击下载
Android 一个改善的okHttp封装库相关推荐
- Android okHttp封装库(2) -- okhttp-OkGo
OkGo - OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持RxJava 该库是封装了okhttp的标准RESTful风格的网络框架,可以与RxJava完美结合,比Retrof ...
- Android客户端连接服务器- OKHttp的简单实用方法
文章目录 一 .OKHttp简介 二. OkHttp3使用 1.创建HTTPClient实例 2.Get请求 3.POST请求 三.Timeouts(超时) **写在前面:本文只是对OKHttp3的简 ...
- android开发常用组件和第三方库(二)
TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending, github搜索:https://github.com ...
- Android好用的第三方开源库
记录一些对工作学习有帮助的第三方开源库 快捷入口 音频类 AudioPlay Banner类 banner 流式布局 FlowLayout 网络请求框架 RxEasyHttp okhttp-RxHtt ...
- 建立自己的封装库(一)
经常会遇到需要自己画封装的情况,之前每次都是一个原件新建一个原理图库和pcb库,而且有没有联系起来,时间长了会发现很乱,而且也会养成不好的习惯,后来在网上找过很多资料,建立了一个属于自己的封装库,方便 ...
- 打造Altium Designer 3D封装库
看到Andy_2020发的帖子"Altium Designer专题"之后,对Altium Designer的3D功能很感兴趣,着手自己做一个AD的3D封装库.刚开始按照Andy介绍 ...
- NFC芯片NT3H1101W0FHKH封装库以及手册
自己画的一个NFC芯片的封装库 顺便附上手册! https://github.com/1106525618/NFC
- Android线程池封装库
目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...
- Android之全面解析Retrofit网络框架封装库
转载请标明出处:[顾林海的博客] 前言 Retrofit是Square公司推出的一个HTTP的框架,主要用于Android和Java,Retrofit会将每一个HTTP的API请求变成一个Java的接 ...
最新文章
- C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员
- Gh0st源码学习(三)生成DLL和DAT文件
- vue 3.0 正式版_Vuejs 3 Release:One Piece. Vuejs 3.0 正式版发布!代号:海贼王
- ManualResetEvent详解
- 【并查集】noi2001食物链
- 支持FreeMarker需要哪些JAR包?
- c语言调用sqlite
- Oracle学习总结(6)—— SQL注入技术
- 搭建LINUX BIND实现DNS解析
- Kubernetes 1.5安装
- 不能错过的linux驱动开发的经典书籍推荐
- 关于ISO27001信息安全管理体系的内容详细概括
- 支付宝、京东支付场景之策略模式实战
- 如何利用RFM模型对客户进行精细化管理
- 基于Matlab高斯光束前向与后向传播的模拟
- 诺基亚5320XM 上的最好的手机浏览器,UCWEB 6
- ai面试的优缺点_AI面试需要注意哪些问题?
- C语言的程序设计流程、特点及要求
- 部门换届推文文字_宿委会换届表彰大会!!!
- symfony简单的博客练习,熟悉具体开发流程