RHttp 是基于 RxJava2 + Retrofit2 + OkHttp3 + RxLifecycle2 框架整合封装的网络请求框架
- 基本的get、post、put、delete、4种请求
- 单/多文件上传
- 断点续传下载
- 基本回调包含 onSuccess、onError、onCancel、onProgress(上传/下载带进度)
- 支持自定义Callback
- 支持https
- 支持tag取消,支持取消全部请求
- 支持绑定组件生命周期自动管理网络请求
- 支持链式调用
- 支持表单格式,String,json格式数据提交请求
RHttp 很屌吗?算不上,基本满足应用开发的所有需求,代码很简洁,体积小,功能齐全。这就够了
- 基于主流网络框架 Retrofit2 + OkHttp3 作为底层框架
- 使用 RxJava2 处理异步事件,线程间切换逻辑
- 使用 RxLifecycle2 管理生命周期,再也不用担心 RxJava 使用不当造成内存泄漏
- 基础网络请求,数据转换为 String 并提供 onConvert 方法提供开发者自定义转化数据
- 上传带进度回调,多文件情况下,可以区分当前文件下标
- 断点续传大文件,多种下载状态满足不同下载需求
为了 RHttp 框架需求,使用前必须要初始化
如果你很懒,只为快速上手。可以使用最基础的初始化。例如在 Application
public class RApp extends Application {
@Override
public void onCreate() {
super.onCreate();
//必须初始化RHttp
RHttp.Configure.get().init(this);
}
}
如果你需求比较复杂,可以配置一些全局参数以满足复杂的需求,以下是全部可选配置,开发者按需设置
//初始化RHttp(全局配置)
RHttp.Configure.get()
.timeout(30)//请求超时时间
.timeUnit(TimeUnit.SECONDS)//超时时间单位
.baseHeader(new HashMap<String, Object>())//全局基础header,所有请求会包含
.baseParameter(new HashMap<String, Object>())//全局基础参数,所有请求会包含
.baseUrl("http://com.ruffian.http.cn")//基础URL
.showLog(true)//是否显示调试log
.init(this);//初始化,必须调用
以下是请求所有可配置参数,开发者按需设置
RHttp http = new RHttp.Builder()
.post()// 任选一种请求方式 .post().get().put().delete()
.baseUrl("http://apicloud.mob.com/")//基础路径 如果全局配置了,这里可以省略
.apiUrl("user/login")//接口路径 如果不需要可以不填
.addParameter(new HashMap<String, Object>())//增加参数,重复调用可叠加
.setParameter(new HashMap<String, Object>())//设置参数,覆盖之前设置
.addHeader(new HashMap<String, Object>())//增加Header,重复调用可叠加
.setHeader(new HashMap<String, Object>())//设置Header,覆盖之前设置
//设置String 类型参数 覆盖之前设置 isJson:是否强制JSON格式 bodyString设置后Parameter则无效
.setBodyString(new Gson().toJson(user), true) //String/json格式提交数据
.tag("someTag")//设置TAG 后续可根据tag取消请求
.file(Map<String, File> file)//map方式设置file文件
.file(String key, List<File> fileList)//一个key对应多个文件
.lifecycle(this)//设置自动管理生命周期 Activity/Fragment 继承 RxLifecycle (不设置可能导致RxJava使用内存泄漏)
.activityEvent(ActivityEvent.STOP)//手动管理属于Activity (此属性前提必须设置lifecycle)
.fragmentEvent(FragmentEvent.DESTROY_VIEW)//手动管理属于Fragment (此属性前提必须设置lifecycle)
.timeout(60)//本次请求超时时间,未设置使用全局配置
.timeUnit(TimeUnit.SECONDS)//超时时间单位,未设置使用全局配置
.build();
addParameter(Map<String, Object> parameter)
表示添加参数,重复调用可叠加setParameter(Map<String, Object> parameter)
表示重置参数,清空之前设置addHeader(Map<String, Object> header)
增加Header,重复调用可叠加setHeader(Map<String, Object> header)
设置Header,覆盖之前设置setBodyString(String text,boolean isJson)
(仅POST)表示String/json
格式提交数据,会使add/setParameter
设置的参数无效;boolean isJson
参数意义:true
表示json格式 ;false
表示String格式baseUrl(String baseUrl)
基础URL,如果全局配置了,这里可以省略apiUrl(String apiUrl)
基础路径 如果不需要可以不设置lifecycle(LifecycleProvider lifecycle)
自动管理生命周期,防止RxJava内存泄漏activityEvent(ActivityEvent activityEvent)
适用于Activity的指定生命周期管理 依赖于lifecycle
已经设置fragmentEvent(FragmentEvent fragmentEvent)
适用于Fragment的指定生命周期管理 依赖于lifecycle
已经设置file(Map fileMap)
上传文件时,文件mapfile(String key,List<File> list)
上传文件时,文件list 适用一个key对应多个文件timeout(long timeout)
本次请求超时时间,未设置使用全局配置timeUnit(TimeUnit timeUnit)
超时时间单位,未设置使用全局配置
RHttp 对象提供一些可用 api 接口。如:发起请求 , 取消请求
//构建 RHttp 对象
RHttp http = new RHttp.Builder()
.tag("login_request")//设置请求tag,以便后续根据tag取消请求
.build();//构建http对象
//RHttp可用 api
http.execute(new RHttpCallback() {});//执行请求(get/post.delete/put)
http.execute(new RUploadCallback() {});//执行请求(文件上传)
http.cancel();//取消当前网络请求
http.isCanceled();//当前网络请求是否已经取消
//静态方法
RHttp.cancel("login_request");//根据tag取消指定网络请求
RHttp.cancelAll();//取消所有网络请求
execute(HttpCallback httpCallback)
执行普通Http请求execute(UploadCallback uploadCallback)
执行上传文件请求 执行请求,重载函数,根据传入Callback
执行执行不同的请求cancel()
取消当前网络请求isCanceled()
当前网络请求是否已经取消RHttp.cancel(String tag)
根据tag取消指定网络请求RHttp.cancelAll()
取消所有网络请求
new HttpCallback<T>() {
@Override
public T onConvert(T data) throws Exception {
//数据转换/解析
//开发者自己实现如何将 data 转化为 泛型指定 数据
return data;
}
@Override
public void onSuccess(Object value) {
}
@Override
public void onError(int code, String desc) {
}
@Override
public void onCancel() {
}
@Override
public boolean isBusinessOk() {
return false;
}
}
http.request(new HttpCallback<String>() {
@Override
public String onConvert(String data) {
//数据转换/解析
//开发者自己实现如何将 data 转化为 泛型指定 数据
return data;
}
@Override
public void onSuccess(String value) {
}
@Override
public void onError(int code, String desc) {
}
@Override
public void onCancel() {
}
});
public String onConvert(String data)
是数据转化/解析的回调函数,通过指定泛型 在这里解析之后框架会将返回值String
(或者其他bean) 回调给onSuccess
可以直接使用;如果解析数据出错,回调onError
public void onSuccess(String value)
成功回调 通过指定泛型得到最终结果,解析和转换交由onConvert
实现public void onError(int code, String desc)
错误/失败回调 code错误码 desc错误信息public void onCancel()
取消回调
UploadCallback<T>
继承于 HttpCallback<T>
具有相同的基本功能,额外增加 进度回调接口
http.upload(new UploadCallback<UserBean>(){
@Override
public void onProgress(File file, long currentSize, long totalSize, float progress, int currentIndex, int totalFile) {
}
@Override
public UserBean onConvert(String data) {
//开发者自己实现如何将 String 转化为对应的 JavaBean
return new Gson().fromJson(data, UserBean.class);
}
@Override
public void onSuccess(UserBean value) {
}
@Override
public void onError(int code, String desc) {
}
@Override
public void onCancel() {
}
});
public void onProgress(File file, long currentSize, long totalSize, float progress, int currentIndex, int totalFile)
上传进度回调
file:
正在上传的文件currentSize:
已上传totalSize:
文件总大小progress:
进度currentIndex:
当前上传文件下标totalFile:
此次上传总文件数
- 其他回调与
HttpCallback
一样
我们看到,框架提供的 HttpCallback<T>
的 onConvert(String data)
传进来的参数是 String
也就是说,RHttp
将请求到的数据转化为 String
类型
将数据从 String
开始解析麻烦了一点,对于一些规范数据,比如:
{
"code": 200
"msg": "success",
"result": {},
}
对于这种数据格式,如果全部从 String 开始解析,那太蛋疼,进一步封装
定义一个 Response
用于快速解析服务器返回数据
public class HttpResponse implements Serializable {
/*描述信息*/
@SerializedName("msg")
private String msg;
/*状态码*/
@SerializedName("code")
private int code;
/*数据对象*/
@SerializedName("result")
private JsonElement result;
/**
* 是否成功(这里可以与服务器约定)
* 备注:这里约定 code==200 认为这次请求逻辑成功
*
* @return
*/
public boolean isSuccess() {
return code == 200;
}
public String toString() {
String response = "[http response]" + "{\"code\": " + code + ",\"msg\":" + msg + ",\"result\":" + new Gson().toJson(result) + "}";
return response;
}
//get/set
}
这里我们最终需要使用的大部分是 result
转成对应的 JavaBean
就可以了
对于 code
不等于 200
的错误逻辑,可以回调 onError(int code, String desc)
认为逻辑失败了,例如:登录返回 code=123 msg=密码错误
自定义Callback示例
public abstract class RHttpCallback<T> extends HttpCallback<T> {
@Override
public T onConvert(String data) {
/**
* 接口响应数据格式如@Response
* 将result转化给success
* 这里处理通过错误
*/
T t = null;
Response response = new Gson().fromJson(data, Response.class);
int code = response.getCode();
String msg = response.getMsg();
JsonElement result = response.getResult();
switch (code) {
case 101://token过期,跳转登录页面重新登录(示例)
break;
case 102://系统公告(示例)
break;
default:
if (response.isSuccess()) {//与服务器约定成功逻辑
t = convert(result);
} else {//统一为错误处理
onError(code, msg);
}
break;
}
return t;
}
/**
* 数据转换/解析
*
* @param data
* @return
*/
public abstract T convert(JsonElement data);
/**
* 成功回调
*
* @param value
*/
public abstract void onSuccess(T value);
/**
* 失败回调
*
* @param code
* @param desc
*/
public abstract void onError(int code, String desc);
/**
* 取消回调
*/
public abstract void onCancel();
}
public abstract class DownloadCallback<T extends Download> {
/**
* 进度回调
*
* @param state 下载状态
* @param currentSize 当前已下载
* @param totalSize 文件总大小
* @param progress 进度
*/
public abstract void onProgress(Download.State state, long currentSize, long totalSize, float progress);
/**
* 下载出错
*
* @param e
*/
public abstract void onError(Throwable e);
/**
* 下载成功
*
* @param object
*/
public abstract void onSuccess(T object);
}
void onProgress(Download.State state, long currentSize, long totalSize, float progress);
下载进度回调
State:
下载状态currentSize:
已下载totalSize:
文件总大小progress:
进度
onSuccess(T object)
下载成功回调T
可以是Download
或其子类onError(Throwable e)
下载失败
框架下载类 Download
public class Download implements Serializable {
@PrimaryKey(AssignType.AUTO_INCREMENT)
@Column("id")
private long id;
@Column("localUrl")
private String localUrl;//本地存储地址
@Column("serverUrl")
private String serverUrl;//下载地址
@Column("totalSize")
private long totalSize;//文件大小
@Column("currentSize")
private long currentSize;//当前大小
@Column("state")
private State state = State.NONE;//下载状态
@Ignore
private Api api;//接口service
@Ignore
private DownloadCallback callback;//回调接口
/**
* 枚举下载状态
*/
public enum State {
NONE, //无状态
WAITING, //等待
LOADING, //下载中
PAUSE, //暂停
ERROR, //错误
FINISH, //完成
}
}
拓展下载实体类 使用框架的 Download
或者其子类
public class DownloadBean extends Download {
/**
* 额外字段,apk图标
*/
private String icon;
public DownloadBean(String url,String icon,String localUrl) {
setServerUrl(url);
setLocalUrl(localUrl);
setIcon(icon);
}
//get/set
}
构建下载
//文件存储路径和名称
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "QQ.apk");
//下载地址
String url = "http://imtt.dd.qq.com/16891/FC92B1B4471DE5AAD0D009DF9BF1AD01.apk?fsname=com.tencent.mobileqq_7.7.5_896.apk&csr=1bbd";
//额外参数icon
String icon = "http://pp.myapp.com/ma_icon/0/icon_6633_1535456193/96";
DownloadBean bean = new DownloadBean(url, icon, file.getAbsolutePath());
/*设置回调监听*/
bean.setCallback(new DownloadCallback<DownloadBean>() {
@Override
public void onProgress(Download.State state, long currentSize, long totalSize, float progress) {
//State: NONE=无状态 WAITING=等待 LOADING=下载中 ERROR=错误 FINISH=完成
//currentSize 已下载
//totalSize 文件大小
//progress 进度
}
@Override
public void onError(Throwable e) {
}
@Override
public void onSuccess(DownloadBean object) {
//下载成功
//object.getLocalUrl();
}
});
/*开始/继续*/
RDownLoad.get().startDownload(bean);
/*暂停*/
RDownLoad.get().stopDownload(bean);
/*暂停全部*/
RDownLoad.get().stopAllDownload();
/*移除下载*/
RDownLoad.get().removeDownload(bean);
/*下载中列表*/
RDownLoad.get().getDownloadList(DownloadBean.class);
void startDownload(Download download)
开始/继续下载void stopDownload(Download download)
停止下载void stopAllDownload()
停止全部下载任务void removeDownload(Download download)
移除下载,正在下载中会先暂停再移除public <T> List<T> getDownloadList(Class<T> tClass)
获取正在下载列表<T extends Download>
tClass
必须是Download
或者其子类