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 ...
随机推荐
- axis和cxf集成Springmvc的使用
一.使用axis用wsdl生成Webservice: 工具:有axis插件的eclipse,wsdl文件: 操作步骤: 新建工程-->选择wsdl文件-->右键选择Webservice-- ...
- 使用SoapUI工具做get请求和post请求接口测试
祝大家节日快乐啦. 之前写过的一篇帖子已经介绍了SoapUI工具的基本使用,所以在此不再重复讲解关于建工程.建测试套件.添加用例等操作,可查看该篇文章详解:http://www.cnblogs.com ...
- Find 找规律,递推
Find Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus P ...
- Free Goodies UVA - 12260 贪心
Free Goodies Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu [Submit ...
- POJ1032 Parliament(数论)
New convocation of The Fool Land's Parliament consists of N delegates. According to the present regu ...
- 经典算法研究系列:二、Dijkstra 算法初探
July 二零一一年一月 本文主要参考:算法导论 第二版.维基百科. 一.Dijkstra 算法的介绍 Dijkstra 算法,又叫迪科斯彻算法(Dijkstra),算法解决的是有向图中单个源点到 ...
- 简单说明如何设置系统中的NLS_LANG环境变量
概述:本地化是系统或软件运行的语言和文化环境.设置NLS_LANG环境参数是规定Oracle数据库软件本地化行为最简单的方式.NLS_LANG参数不但指定了客户端应用程序和Oracle数据库所使用的语 ...
- 学习如何看懂SQL Server执行计划(三)——连接查询篇
三.连接查询部分 --------------------嵌套循环-------------------- /* UserInfo表数据少.Coupon表数据多嵌套循环可以理解为就是两层For循环,外 ...
- File FileStream StreamWriter StreamReader文件读写操作方法
string path = "D:\\AccountChecking\\Test.txt"; string content = "abcdefg\r\nhigklmn\r ...
- 使用Entify Framework 6.x的事务操作
public void TransactionsTest() { using (var context = new testContext()) { //使用EF事务 在vs2013中先升级Entit ...