Android-Async-Http 特性简单分析
如下是官方文档描述此库的特点:
All requests are made outside of your app’s main UI thread, but any callback logic will be executed on the same thread as the callback was created using Android’s Handler message passing.
•Using upstream HttpClient of version 4.3.6 instead of Android provided DefaultHttpClient
•Compatible with Android API 23 and higher
•Make asynchronous HTTP requests, handle responses in anonymous callbacks
•HTTP requests happen outside the UI thread
•Requests use a threadpool to cap concurrent resource usage
•GET/POST params builder (RequestParams)
•Multipart file uploads with no additional third party libraries
•Streamed JSON uploads with no additional libraries
•Handling circular and relative redirects
•Tiny size overhead to your application, only 90kb for everything
•Automatic smart request retries optimized for spoĴy mobile connections
•Automatic gzip response decoding support for super-fast requests
•Binary protocol communication with BinaryHttpResponseHandler
•Built-in response parsing into JSON with JsonHttpResponseHandler
•Saving response directly into file with FileAsyncHttpResponseHandler
•Persistent cookie store, saves cookies into your app’s SharedPreferences
•Integration with Jackson JSON, Gson or other JSON (de)serializing libraries with BaseJsonHttpResponseHandler
•Support for SAX parser with SaxAsyncHttpResponseHandler
•Support for languages and content encodings, not just UTF-8
•1、兼容Android API23或更高版本
•2、发送异步的http请求,在匿名的回调callback中处理响应response
•3、Http的请求发生在主线程之外
•4、使用线程池处理并发请求
•5、使用RequestParams构造GET、POST请求参数
•6、流式Json上传,无需三方库支持
•7、能处理环形和相对重定向
•8、内置multiPart file 上传,无需第三方库支持
•9、相比app来说库很小,仅仅只有90k
•10、针对移动连接自动智能的请求重试优化机制
•11、自动的gzip响应解码
•12、支持字节流响应处理 BinaryHttpResponseHandler
•13、内置Json文本响应处理 JsonHttpResponseHandler
•14、持久化Cookie信息,将Cookie信息保存在应用的SharedPreference中
•15、通过实现抽象类BaseJsonHttpResponseHandler可以无缝对接三方Json解析库
•16、支持SAX解析器 SaxAsyncHttpResponseHandler
•17、支持各种语言和content编码,不止是UTF-8
Android-Async-Http 源码版本1.4.9
在AsyncHttpClient的构造方法中有对连接各种参数的设置,并实例化了一个默认的线程池threadPool(Executors.newCachedThreadPool)用于提交请求任务AsyncHttpRequest,接着初始化了httpClient,并给请求和响应添加了拦截器以实现自动的gzip解码,调用AsyncHttpRequest实例的get post等方法时最终会调用sendRequest方法,sendRequest方法接收httpClient、responseHandler、uriRequest等参数,在方法内部会构造请求的AsyncHttpRequest对象(newAsyncHttpRequest),并通过threadPool.submit(request)方法提交到线程池中,何为异步就体现在这里。
AsyncHttpRequest实现了Runnable接口,它的run方法就是核心代码,调用responseHandler.sendxxx 方法以实现各种方法回调和请求结果投递,在makeRequestWithRetries中有重试的逻辑,具体在retryHandler中有重试次数的判断,当重试次数超过最大值时(默认是5次),跳出while循环,这里重试的逻辑和Volley中的处理类似 。
其中AsyncHttpClient中默认的线程池没有核心线程,只有work线程,且工作线程的存活时间是60s,如果此种线程池不能满足需要,可以实现自己的线程池,并调用setThreadPool方法。
其中在调用AsyncHttpClient中各种请求方法时,会传入请求响应的各式xxxResponseHandler,针对不同的响应数据类型,有TextHttpResponseHandler、JsonHttpResponseHandler、FileHttpResponseHandler等,这些xxxResponseHandler中封装了Handler和Looper,因为构造Handler是需要先有Looper的,而looper的初始化是在AsyncHttpResponseHandler构造函数中,
this.looper = looper == null ? Looper.myLooper() : looper,即如果没有传入looper则使用当前线程的looper(即创建xxxResponseHandler的线程,可能是主线程也可能是子线程)。 这些xxxResponseHandler都继承自AsyncHttpResponseHandler类,并实现了
onSuccess(int statusCode, Header[] headers, byte[] responseBody) 和 onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error)方法,以处理不同返回数据类型的响应。
如上叙述印证了2 、3、4、10、11条结论。
---------------------------------------------------------------------------------------------------------------------------------------------
上传图片文件到chuantu.biz,代码如下
AsyncHttpClient httpClient = new AsyncHttpClient();
RequestParams params = new RequestParams(); try {
String filePath = getBaseContext().getExternalCacheDir().getPath() + File.separator + "IMG_20171106_202814.jpg";
File file = new File(filePath);
if (file.exists()) {
params.put("uploadimg", file, "image/jpeg");
} } catch (FileNotFoundException e) {
e.printStackTrace();
} httpClient.setProxy("172.20.10.2", 8888); httpClient.post(this, "http://www.chuantu.biz/upload.php", /*headers,*/ params,/* null,*/ new TextHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, String responseBody) {
printHeaders(headers);
Log.d(TAG, responseBody);
} @Override
public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable error) { }
});

如上印证了5 、8 两条特性。
上传文件时,会调用RequestParams中的createMultipartEntity方法,其中SimpleMulitpartEntity的addPart方法会添加待写入流中的文件信息,之后将文件内容的字节写入到流中,具体见SimpleMultipartEntity的writeTo方法,其中SimpleMultipartEntity类实现了HttpEntity接口,其中重写了getContentType方法,此方法中返回标识性的header信息,Content-Type:multipart/form-data;boundary= xxxxxx, 分界线标识的字符串是在数字大小写字符等字符中随机抽取出来的30个字符组成。
需要注意到构造AsyncHttpRequest时最后的参数context, 如果context不为空,请求会被放到
Map中,以便在Activity onPause的时候或者onDestory的时候取消掉无用的请求等。
-------------------------------------------------------------------------------------------------------------------
BaseJsonHttpResponseHandler的使用
先添加Gson依赖,compile 'com.google.code.gson:gson:2.8.1'
这里以kuaidi100的快递数据为例:http://www.kuaidi100.com/query?type=xxx&postid=xxxx
先创建一个快递数据类的实体(这里字段并不全,只是为了说明问题,具体可以自行调试接口)
public class Express {
public String message;
public String nu;
public int isCheck;
public String com;
public int status;
public int state;
public Express(String message, String nu, int isCheck, String com, int status, int state) {
this.message = message;
this.nu = nu;
this.isCheck = isCheck;
this.com = com;
this.status = status;
this.state = state;
}
@Override
public String toString() {
return "Express{" + "message='" + message + '\'' + ", nu='" + nu + '\'' + ", isCheck=" + isCheck
+ ", com='" + com + '\'' + ", status=" + status + ", state=" + state + '}';
}
}
创建RequestParams 发起GET请求
RequestParams params = new RequestParams();
params.put("type", "shunfeng");
params.put("postid", "384566812983"); httpClient.get("http://www.kuaidi100.com/query", params, new BaseJsonHttpResponseHandler<Express>() {
@Override
public void onSuccess(int statusCode, Header[] headers, String rawJsonResponse, Express response) {
Log.d(TAG, "response = " + response);
} @Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData, Express errorResponse) { } @Override
protected Express parseResponse(String rawJsonData, boolean isFailure) throws Throwable {
Gson gson = new Gson();
return gson.fromJson(rawJsonData, Express.class);
}
});
Android-Async-Http 特性简单分析的更多相关文章
- Android事件拦截机制简单分析
前一阶段,在学习的时候,遇到了我觉得的我接触安卓以来的最多的一次事件拦截出来,那个项目,用到了slidemenu側滑菜单条,然后加上tab标签,还有轮播广告,listview上下滑动.viewpage ...
- Android.mk文件简单分析
Android.mk文件简单分析 一个Android.mk文件用来向编译系统描写叙述须要编译的源码.详细来说:该文件是GNUMakefile的一小部分.会被编译系统解析一次或多次. 能够在每个Andr ...
- Android实现录屏直播(一)ScreenRecorder的简单分析
http://blog.csdn.net/zxccxzzxz/article/details/54150396 Android实现录屏直播(一)ScreenRecorder的简单分析 Android实 ...
- android关于AndroidManifest.xml详细分析
http://my.eoe.cn/1087692/archive/5927.html 一.关于AndroidManifest.xmlAndroidManifest.xml 是每个android程序中必 ...
- FFmpeg源代码简单分析:configure
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- Android N 新特性
2016年5月19日,谷歌在美国加州的山景城举办了 Google I/O 开发者大会中发布.2016年6月,Android N正式命名为“牛轧糖” 本届I/O开发者大会上,Google重点介绍了And ...
- 吴裕雄--天生自然Android开发学习:android 背景相关与系统架构分析
1.Android背景与当前的状况 Android系统是由Andy Rubin创建的,后来被Google收购了:最早的版本是:Android 1.1版本 而现在最新的版本是今年5.28,Google ...
- 简单分析JavaScript中的面向对象
初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...
- Xamarin.Android之封装个简单的网络请求类
一.前言 回忆到上篇 <Xamarin.Android再体验之简单的登录Demo> 做登录时,用的是GET的请求,还用的是同步, 于是现在将其简单的改写,做了个简单的封装,包含基于Http ...
随机推荐
- 关于el-dialog,我更推荐的用法
最近的项目里用上了vue和element-ui.vue这种轻量级渐进式框架的舒适自不必说,但一直困扰着我的,是如何方便又优雅的弹出模态dialog... 对于我这种在jquery出现之前就用docum ...
- Access-Control-Allow-Origin与Ajax跨域
问题 在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题.另一个域名必须在response中添加 Access-Control-Allow-Origin 的header,才能让前者成功 ...
- NodeJS 初学之安装配置环境
[TOC] 1.环境安装 操作系统: Ubuntu 16.04.2 LTS 1.1安装nvm ryan@ryan-900X5L:~/temp$ curl https://raw.githubuserc ...
- Git命令(1)
windows中文乱码: http://www.cnblogs.com/Gukw/archive/2012/01/16/2323417.html 学习地址 :http://www.liaoxuefen ...
- HandlerMapping 和 HandlerAdapter
HandlerMapping 负责根据request请求找到对应的Handler处理器及Interceptor拦截器,将它们封装在HandlerExecutionChain 对象中给前端控制器返回. ...
- 关于celery django django-celery版的搭配的报错问题及解决方法
G:\python3_django\DFpro\mypro (win)(py3_django) λ python manage.py celery worker --loglevel=infoTrac ...
- css3中“渐变”兼容性解决方案
这次是简单的谈一下我们常见的渐变在各个浏览器下的兼容性问题,算一个比较简单的问题. 我们熟知的浏览器有Chrome.Firefox.Opera.Safari以及ie系列.最基础的background: ...
- URL的编码和解码
URL的编码和解码 参考:阮一峰--关于URL编码 1 为什么要URL编码 在因特网上传送URL,只能采用ASCII字符集 也就是说URL只能使用英文字母.阿拉伯数字和某些标点符号,不能使用其他文字和 ...
- ajax 轮询 和 php长连接
只看加粗的字体 js 部分 1: ajax 成功回调函数中 一定要用时间函数间隔调用 get_comment(). get_comments('init'); function ...
- Nodejs.热部署方法
在开发中我们修改了一点代码后要去重启服务器才能看到结果,为了省去这个过程我们以往经常使用热部署代码的方法 下面是使用"supervisor"来达到热部署能力的方法: sudo np ...