本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。
本系列文章目录总览: http://blog.csdn.net/ko33600/article/details/49367409
1. 初始化及单例
初始化LiteHttp需要传入一个HttpConfig的实例来配置各项参数,若传入null即表示使用全部使用默认设置。
需要注意的是,一个App仅需要构建一个LiteHttp的实例即可,即单例模式,这样才能最节省系统资源,多个实例并不提升效率反而浪费资源。
使用默认配置,不是我良辰不给你,你不是很屌吗,自力更生吧:
LiteHttp liteHttp = LiteHttp.newApacheHttpClient(null);
更推荐简单的自定义配置:
HttpConfig config = new HttpConfig(activity) // configuration quickly
.setDebugged(true) // log output when debugged
.setDetectNetwork(true) // detect network before connect
.setDoStatistics(true) // statistics of time and traffic
.setUserAgent("Mozilla/5.0 (...)") // set custom User-Agent
.setTimeOut(10000, 10000); // connect and socket timeout: 10s
liteHttp = LiteHttp.newApacheHttpClient(config);
这个案例示范了context(用于网络状态判断),打开调试,探测网络状态,开启数据统计,User-Agent,以及连接和读取超时等参数的配置。
更多的配置项有达23+项之多,比较灵活,后边会有专门章节详细说明。
下面讲解如何发起请求,我们首先定义合法的http地址,如:
String url = "http://baidu.com";
String picUrl = "http://pic.33.la/20140403sj/1638.jpg";
2. 发起同步请求
撸一行代码即可,节省的时间爷沏一杯菊花茶:
String html = liteHttp.perform(new StringRequest(url));
构建一个请求,通过litehttp执行获取结果,当然无需回调,直截了当。
再撸一行,获取一张美图:
Bitmap bitmap = liteHttp.perform(new BitmapRequest(picUrl));
注意:同步请求在当前线程直接执行,应用需开启子线程执行。
3. 发送异步请求
异步请求获取String:
liteHttp.executeAsync(new StringRequest(url));
异步获取原始byte:
liteHttp.executeAsync(new BytesRequest(url));
异步加载一张位图:
String saveToPath = "/sdcard/a.png";
liteHttp.executeAsync(new BitmapRequest(url,saveToPath));
saveToPath用来输入一个你指定的文件位置,位图将会保存到这里,传入null则保存默认位置。
异步下载一个文件:
liteHttp.executeAsync(new FileRequest(url,saveToPath));
saveToPath 用来输入一个你指定的文件位置,文件将会保存到这里,传入null则保存缓存默认位置。
文件默认存储位置和命名规则:
- 统一存放到 HttpConfig 设置指定的文件夹中。
- 请求已设置 Cache-Key,则取其为文件名字。
- 请求未设置 Cache-Key,则通过处理 Url 自动生成文件名字。
我们知道了怎么发起异步请求,那么请求是成功还是失败,成功如何获取结果,失败如何获取异常?
4. UI线程 监听和处理响应
同步 获取 String,在 UI线程 处理结果或异常:
// 主线程处理,注意HttpListener默认是在主线程回调
// get data in listener, handle result on UI thread
liteHttp.execute(new StringRequest(url).setHttpListener(
new HttpListener<String>() {
@Override
public void onSuccess(String data, Response<String> response) {
response.printInfo();
}
}
));
异步 下载 File,在 UI线程 监听进度:
liteHttp.executeAsync(new FileRequest(url,saveToPath).setHttpListener(
new HttpListener<File>(true, true, true) {
@Override
public void onLoading(AbstractRequest<Bitmap> request, long total, long len) {
// 进度通知
}
})
);
5. 当前线程 监听和处理响应
同步 加载位图,在 当前线程 监听HttpListener构造函数第一个参数设置为false即可;第二、三个参数设置为true开启上传、下载进度监听:
// 2.2 return data directly, and handle result on current thread(当前主线程处理)
Bitmap bitmap = liteHttp.perform(new BitmapRequest(picUrl)
.setHttpListener(new HttpListener<Bitmap>(false, true, true) {
@Override
public void onLoading(AbstractRequest<Bitmap> request, long total, long len) {
// down loading notification ...
}
@Override
public void onUploading(AbstractRequest<Bitmap> request, long total, long len) {
// up loading notification...
}
}));
异步 获取 String,在 当前线程 处理结果,HttpListener构造函数参数设置为false即可:
liteHttp.executeAsync(new StringRequest(url)
.setHttpListener(new HttpListener<String>(false) {
@Override
public void onSuccess(String s, Response<String> response) {
// 成功:主线程回调,反馈一个string
response.printInfo();
}
@Override
public void onFailure(HttpException e, Response<String> response) {
// 失败:主线程回调,反馈异常
response.printInfo();
}
})
);
其他模式的请求用法一样,这里不再多举。
6. 推荐通过注解完成请求
请求默认是GET方式,假设完成一个登陆操作,API和参数为http://xxx?name=lucy&password=123456,登陆成功返回User对象,我们有以下接口:
public String loginUrl = "http://litesuits.com/mockdata/user_get";
该接口的响应体是个Json字符串:
{
"api": "com.xx.get.userinfo",
"v": "1.0",
"result": {
"code": 200,
"message": "success"
},
"data": {
"age": 18,
"name": "qingtianzhu",
"girl_friends": [
"xiaoli",
"fengjie",
"lucy"
]
}
}
根据该Json响应,对应的 User 类如下:
public class User {
private String api;
private String v;
protected int code;
protected String message;
protected Data data;
public static class Data {
public int age;
public String name;
public ArrayList<String> girl_friends;
}
}
通过注解约定的方式配置代码如下,更清晰:
// 1.1 地址:loginUrl
// 1.2 参数:name=value&password= value
// 1.3 响应:成功返回 User 对象
@HttpUri(loginUrl)
class LoginParam extends HttpRichParamModel<User> {
private String name;
private String password;
public LoginParam(String name, String password) {
this.name = name;
this.password = password;
}
}
// 2. 一句话调用即实现登陆和监听
liteHttp.executeAsync(new LoginParam("lucy", "123456").setHttpListener(
new HttpListener<User>() {
@Override
public void onSuccess(User user, Response<User> response) {
HttpUtil.showTips(activity, "对象自动转化", user.toString());
}
}
));
LoginParam 一个类定义了 API地址、参数、响应体 三个关键数据定义,非常的清晰简单。
7. 请求监听器HttpListener简介
HttpListener各个回调的时机有:开始、成功、失败、取消、重试、上传进度、下载进度、结束。
值得注意的是 HttpListener 有多个参数(构造函数和使用set方法均可)可以设置:
HttpListener(boolean runOnUiThread, boolean readingNotify, boolean uploadingNotify)
分别用于设置:
- 所有回调是否在主线程
- 是否开启下载进度通知
- 是否开启上传进度通知
一般情况下:
- 开始和结束作为开闭节点一定会被调用
- 成功、失败、取消三个作为结果将有一个被调用
- 默认主线程回调,setRunOnUiThread设置为false将在本线程回调,性能更高,但不可操作UI。
- 下载进度通知仅在setReadingNotify设置为true时触发调用
- 上传进度通知仅在setUploadingNotify设置为true时触发调用
- 通过setLinkedListener来设置一个级联的监听器
- 通过setDelayMillis来设置 所有 回调方法的延时,以方便调试
- 复写disableListener来动态设置禁用回调,返回true则 所有 的回调都被禁用。
其他更多最佳实践方式在请关注另外分析文章。
8. 本章总结
- 监听器 HttpListener 很强大,不论同步还是异步请求都可灵活运用。
- 同步请求方式之 perform:返回明确类型的data数据,直接简单。
- 同步请求方式之 execute:返回完整响应体response,包含header,status,data等各种数据。
- 异步请求方式之 performAsync:返回可取消任务FutureTask。
- 异步请求方式之 executeAsync:无返回,调用request的cancel方法取消。
- 异步方法以Async结尾,非安全同步请求以OrThrow结尾,很容易分辨和调用。
- 和普通同步请求的区别是 非安全同步请求 是将异常直接抛出,由开发者自己捕获异常。
- 普通方法是安全的,异常可通过监听器onFailure()捕获,或者response.getException()获取。
- 另外Response对象很重要,几乎拥有一切关于请求的数据,可调用response.printInfo()来打印所有请求相关的信息以便调试。
- 注解很方便,层次和配置更清晰,推荐在实践中使用。
QQ群: 大群 47357508 , 二群 42960650