1. android-async-http   简介

HttpClient拥有众多的API,实现稳定,bug很少。

HttpURLConnection是一种多用途、轻量的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。HttpURLConnection的API比较简单、扩展容易。不过在Android 2.2版本之前,HttpURLConnection一直存在着一些bug。

比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。所以说2.2之前推荐使用HttpClient2.2之后推荐HttpURLConnection

好了,那现在话又说回来,在android-async-http中使用的是HttpClient。哎…好像在Volley中分析过Volley对不同版本进行了判断,所以针对不同版本分别使用了HttpClient和HttpURLConnection。还是google牛逼啊!

回过神继续android-async-http吧,不瞎扯了。android-async-http是专门针对Android在Apache的HttpClient基础上构建的异步http连接。所有的请求全在UI(主)线程之外执行,而callback使用了Android的Handler发送消息机制在创建它的线程中执行

主要有以下功能:

(1)发送异步http请求,在匿名callback对象中处理response信息;

(2)http请求发生在UI(主)线程之外的异步线程中;

(3)内部采用线程池来处理并发请求;

(4)通过RequestParams类构造GET/POST;

(5)内置多部分文件上传,不需要第三方库支持;

(6)流式Json上传,不需要额外的库;

(7)能处理环行和相对重定向;

(8)和你的app大小相比来说,库的size很小,所有的一切只有90kb;

(9)在各种各样的移动连接环境中具备自动智能请求重试机制;

(10)自动的gzip响应解码;

(11)内置多种形式的响应解析,有原生的字节流,string,json对象,甚至可以将response写到文件中;

(12)永久的cookie保存,内部实现用的是Android的SharedPreferences;

(13)通过BaseJsonHttpResponseHandler和各种json库集成;

(14)支持SAX解析器;

(15)支持各种语言和content编码,不仅仅是UTF-8;

附注:

android-async-http项目地址:https://github.com/loopj/android-async-http

android-async-http文档介绍:http://loopj.com/android-async-http/

由上面的项目地址下载开源框架,解压如下:

2. 主要类介绍

  • AsyncHttpRequest

  继承自Runnabler,被submit至线程池执行网络请求并发送start,success等消息

  • AsyncHttpResponseHandler

  接收请求结果,一般重写onSuccess及onFailure接收请求成功或失败的消息,还有onStart,onFinish等消息

  • TextHttpResponseHandler

  继承自AsyncHttpResponseHandler,只是重写了AsyncHttpResponseHandler的onSuccess和onFailure方法,将请求结果由byte数组转换为String

  • JsonHttpResponseHandler

  继承自TextHttpResponseHandler,同样是重写onSuccess和onFailure方法,将请求结果由String转换为JSONObject或JSONArray

  • BaseJsonHttpResponseHandler

  继承自TextHttpResponseHandler,是一个泛型类,提供了parseResponse方法,子类需要提供实现,将请求结果解析成需要的类型,子类可以灵活地使用解析方法,可以直接原始解析,使用gson等。

  • RequestParams

  请求参数,可以添加普通的字符串参数,并可添加File,InputStream上传文件

  • AsyncHttpClient

  核心类,使用HttpClient执行网络请求,提供了get,put,post,delete,head等请求方法,使用起来很简单,只需以url及RequestParams调用相应的方法即可,还可以选择性地传入Context,用于取消Content相关的请求,同时必须提供ResponseHandlerInterface(AsyncHttpResponseHandler继承自ResponseHandlerInterface)的实现类,一般为AsyncHttpResponseHandler的子类,AsyncHttpClient内部有一个线程池,当使用AsyncHttpClient执行网络请求时,最终都会调用sendRequest方法,在这个方法内部将请求参数封装成AsyncHttpRequest(继承自Runnable)交由内部的线程池执行。

  • SyncHttpClient

  继承自AsyncHttpClient,同步执行网络请求,AsyncHttpClient把请求封装成AsyncHttpRequest后提交至线程池,SyncHttpClient把请求封装成AsyncHttpRequest后直接调用它的run方法。

RequestParams的基础使用:

  1. RequestParams params = new RequestParams();
  2. params.put("username", "yanbober");
  3. params.put("password", "123456");
  4. params.put("email", "yanbobersky@email.com");
  5. /**
  6. *Create RequestParams for a single parameter:
  7. */
  8. RequestParams params = new RequestParams("single", "value");
  9. /**
  10. *Create RequestParams from an existing Map of key/value strings:
  11. */
  12. RequestParams params = new RequestParams();
  13. Map<String, String> map = new HashMap<String, String>();
  14. map.put("first_name", "jesse");
  15. map.put("last_name", "yan");
  16. params.put("user", map);
  17. /**
  18. *Upload a File:
  19. */
  20. RequestParams params = new RequestParams();
  21. params.put("file_pic", new File("test.jpg"));
  22. params.put("file_inputStream", inputStream);
  23. params.put("file_bytes", new ByteArrayInputStream(bytes))//bytes is a byte array
  24. /**
  25. *Create RequestParams from an existing set :
  26. */
  27. RequestParams params = new RequestParams();
  28. Set<String> set = new HashSet<String>();
  29. set.add("haha");
  30. set.add("wowo");
  31. params.put("what", set);
  32. /**
  33. *Create RequestParams from an existing List :
  34. */
  35. RequestParams params = new RequestParams();
  36. List<String> list = new ArrayList<String>();
  37. list.add("Java");
  38. list.add("C");
  39. params.put("languages", list);
  40. /**
  41. *Create RequestParams from an existing String[] :
  42. */
  43. RequestParams params = new RequestParams();
  44. String[] colors = { "blue", "yellow" };
  45. params.put("colors", colors);
  46. /**
  47. *Create RequestParams from an existing Map and List (Map in List) :
  48. */
  49. RequestParams params = new RequestParams();
  50. List<Map<String, String>> listOfMaps = new ArrayList<Map<String, String>>();
  51. Map<String, String> user1 = new HashMap<String, String>();
  52. user1.put("age", "30");
  53. user1.put("gender", "male");
  54. Map<String, String> user2 = new HashMap<String, String>();
  55. user2.put("age", "25");
  56. user2.put("gender", "female");
  57. listOfMaps.add(user1);
  58. listOfMaps.add(user2);
  59. params.put("users", listOfMaps);

3. 官方建议使用自己新建静态的AsyncHttpClient:

  1. public class HttpClientUtils {
  2. private static String sessionId = null;
  3. private static AsyncHttpClient client = new AsyncHttpClient();
  4. private static PersistentCookieStore cookieStore ;
  5. static {
  6. //设置网络超时时间
  7. client.setTimeout(5000);
  8. }
  9. public static void get(String url, AsyncHttpResponseHandler responseHandler) {
  10. client.get(url, responseHandler);
  11. }
  12. public static void get(Context context,String url,ResponseHandlerInterface responseHandler) {
  13. client.get(context, url, responseHandler);
  14. }
  15. public static void get(String url,RequestParams params, ResponseHandlerInterface responseHandler) {
  16. client.get(url, params, responseHandler);
  17. }
  18. public static void get(Context context, String url, RequestParams params, ResponseHandlerInterface responseHandler) {
  19. client.get(context, url, params, responseHandler);
  20. }
  21. public static void get(Context context, String url, Header[] headers, RequestParams params, ResponseHandlerInterface responseHandler) {
  22. client.get(context, url, headers, params, responseHandler);
  23. }
  24. public static void post(String url,RequestParams params, ResponseHandlerInterface responseHandler){
  25. client.post(url, params, responseHandler);
  26. }
  27. public static AsyncHttpClient getClient(){
  28. return client;
  29. }
  30. public static String getSessionId() {
  31. return sessionId;
  32. }
  33. public static void setSessionId(String sessionId) {
  34. HttpClientUtils.sessionId = sessionId;
  35. }
  36. public static PersistentCookieStore getCookieStore() {
  37. return cookieStore;
  38. }
  39. public static void setCookieStore(PersistentCookieStore cookieStore) {
  40. HttpClientUtils.cookieStore = cookieStore;
  41. client.setCookieStore(cookieStore);
  42. }
  43. }

4. 请求流程

()调用AsyncHttpClient的get或post等方法发起网络请求。

()所有的请求都走了sendRequest,在sendRequest中把请求封装为了AsyncHttpRequest,并添加到线程池执行。

()当请求被执行时(即AsyncHttpRequest的run方法),执行AsyncHttpRequest的makeRequestWithRetries方法执行实际的请求,当请求失败时可以重试。并在请求开始,结束,成功或失败时向请求时传的ResponseHandlerInterface实例发送消息。

()基本上使用的都是AsyncHttpResponseHandler的子类,调用其onStart,onSuccess等方法返回请求结果。

5. android-async-http最简单基础的使用,只需如下步骤:

  • 创建一个AsyncHttpClient;

  • (可选的)通过RequestParams对象设置请求参数;

  • 调用AsyncHttpClient的某个get方法,传递你需要的(成功和失败时)callback接口实现,一般都是匿名内部类,实现了AsyncHttpResponseHandler,类库自己也提供许多现成的response handler,你一般不需要自己创建。

6. android-async-http 的使用

  • 在匿名callback回调中处理response信息

 (1)新建一个Android工程,如下:

(2)上面要使用到网络访问,自然需要在AndroidManifest中添加网络权限。

(3)来到MainActivity,如下:

  1. package com.himi.asyncresponse;
  2. import org.apache.http.Header;
  3. import com.loopj.android.http.AsyncHttpClient;
  4. import com.loopj.android.http.AsyncHttpResponseHandler;
  5. import android.app.Activity;
  6. import android.os.Bundle;
  7. public class MainActivity extends Activity {
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_main);
  12. AsyncHttpClient client = new AsyncHttpClient();
  13. client.get("https://www.baidu.com/", new AsyncHttpResponseHandler() {
  14. @Override
  15. public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
  16. System.out.println("--------onSuccess------");
  17. System.out.println("反馈结果:");
  18. System.out.println(new String(responseBody));
  19. System.out.println("状态码:"+statusCode);
  20. System.out.println("header:");
  21. for(int i=0; i<headers.length; i++) {
  22. System.out.println(headers[i]);
  23. }
  24. }
  25. @Override
  26. public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
  27. /*System.out.println("--------onFailure------");
  28. System.out.println("反馈结果:"+new String(responseBody));
  29. System.out.println("状态码:"+new String(responseBody));*/
  30. }
  31. @Override
  32. public void onStart() {
  33. super.onStart();
  34. System.out.println("--------onStart------");
  35. }
  36. @Override
  37. public void onFinish() {
  38. super.onFinish();
  39. System.out.println("--------onFinish------");
  40. }
  41. @Override
  42. public void onRetry(int retryNo) {
  43. super.onRetry(retryNo);
  44. System.out.println("--------onRetry------");
  45. }
  46. @Override
  47. public void onCancel() {
  48. super.onCancel();
  49. System.out.println("--------onCancel------");
  50. }
  51. public void onProgress(int bytesWritten, int totalSize) {
  52. super.onProgress(bytesWritten, totalSize);
  53. System.out.println("--------onProgress------");
  54. }
  55. });
  56. }
  57. }

布署程序到模拟器上,观察Logcat如下:

上面是使用Get方法,不带参数的。

下面我们介绍使用Get方法、Post方法带参数的,基本使用如下:

带参数Get请求:

  1. HttpClientUtils.get("http://www.baidu.com", new AsyncHttpResponseHandler() {
  2. @Override
  3. public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
  4. System.out.println(response);
  5. }
  6. @Override
  7. public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable
  8. error)
  9. {
  10. error.printStackTrace(System.out);
  11. }
  12. });

带参数Post请求:

  1. RequestParams params = new RequestParams();
  2. params.put("value1", value1);
  3. params.put("value2", value2);
  4. HttpClientUtils.post(url, params, new JsonHttpResponseHandler(){
  5. @Override
  6. public void onSuccess(int statusCode, Header[] headers,
  7. JSONObject response) {
  8. //请求成功回调
  9. }
  10. @Override
  11. public void onFinish() { //请求完成
  12. }
  13. @Override
  14. public void onFailure(int statusCode, Header[] headers,
  15. String responseString, Throwable throwable) {
  16. //请求失败
  17. }
  18. });
  • 文件上传(支持断点上传)

核心代码示例:

  1. File myFile = new File("/sdcard/test.java");
  2. RequestParams params = new RequestParams();
  3. try {
  4. params.put("filename", myFile);
  5. AsyncHttpClient client = new AsyncHttpClient();
  6. client.post("http://update/server/location/", params, new AsyncHttpResponseHandler(){
  7. @Override
  8. public void onSuccess(int statusCode, String content) {
  9. super.onSuccess(statusCode, content);
  10. }
  11. });
  12. } catch(FileNotFoundException e) {
  13. e.printStackTrace();
  14. }
  • 支持解析成Json格式

(1)JsonHttpResponseHandler带Json参数的POST:

  1. try {
  2. JSONObject json = new JSONObject();
  3. json.put("username", "ryantang");
  4. StringEntity stringEntity = new StringEntity(json.toString());
  5. client.post(mContext, "http://api.com/login", stringEntity, "application/json", new JsonHttpResponseHandler(){
  6. @Override
  7. public void onSuccess(JSONObject jsonObject) {
  8. super.onSuccess(jsonObject);
  9. }
  10. });
  11. } catch (JSONException e) {
  12. e.printStackTrace();
  13. } catch (UnsupportedEncodingException e) {
  14. e.printStackTrace();
  15. }

(2)访问服务器端,获取json数据:

  1. AsyncHttpClient client = new AsyncHttpClient();
  2. String url = "http://172.16.237.227:8080/video/JsonServlet";
  3. client.get(url, new JsonHttpResponseHandler() {
  4. // 返回JSONArray对象 | JSONObject对象
  5. @Override
  6. public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
  7. super.onSuccess(statusCode, headers, response);
  8. if (statusCode == 200) {
  9. //存储数组变量
  10. List<String> objects = new ArrayList<>();
  11. for (int i = 0; i < response.length(); i++) {
  12. try {
  13. // 获取具体的一个JSONObject对象
  14. JSONObject obj = response.getJSONObject(i);
  15. objects.add(obj.getString("name"));
  16. } catch (JSONException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. }
  20. }
  21. //C控制层主要就是对数据处理
  22. ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, objects);
  23. //设置显示的内容
  24. lv_users.setAdapter(adapter);// C空置
  25. }
  26. }
  27. });
  • BinaryHttpResponseHandler下载文件:

  1. AsyncHttpClient client = new AsyncHttpClient();
  2. client.get("http://download/file/test.java", new BinaryHttpResponseHandler() {
  3. @Override
  4. public void onSuccess(byte[] arg0) {
  5. super.onSuccess(arg0);
  6. File file = Environment.getExternalStorageDirectory();
  7. File file2 = new File(file, "down");
  8. file2.mkdir();
  9. file2 = new File(file2, "down_file.jpg");
  10. try {
  11. FileOutputStream oStream = new FileOutputStream(file2);
  12. oStream.write(arg0);
  13. oStream.flush();
  14. oStream.close();
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. Log.i(null, e.toString());
  18. }
  19. }
  20. });
  • PersistentCookieStore持久化存储cookie

官方文档里说PersistentCookieStore类用于实现Apache HttpClient的CookieStore接口,可自动将cookie保存到Android设备的SharedPreferences中,如果你打算使用cookie来管理验证会话,这个非常有用,因为用户可以保持登录状态,不管关闭还是重新打开你的app。

PersistentCookieStore继承自CookieStore,是一个基于CookieStore的子类, 使用HttpClient处理数据,并且使用cookie持久性存储接口。

文档里介绍了持久化Cookie的步骤:

()创建 AsyncHttpClient实例对象;

()将客户端的cookie保存到PersistentCookieStore实例对象,带有activity或者应用程序context的构造方法;

()任何从服务器端获取的cookie都会持久化存储到myCookieStore中,添加一个cookie到存储中,只需要构造一个新的cookie对象,并且调用addCookie方法;

  1. AsyncHttpClient client = new AsyncHttpClient();
  2. PersistentCookieStore cookieStore = new PersistentCookieStore(this);
  3. client.setCookieStore(cookieStore);
  4. BasicClientCookie newCookie = new BasicClientCookie("name", "value");
  5. newCookie.setVersion(1);
  6. newCookie.setDomain("mycompany.com");
  7. newCookie.setPath("/");
  8. cookieStore.addCookie(newCookie);

4. Android框架和工具之 android-async-http的更多相关文章

  1. 13. Android框架和工具之 Android Drawable Factory

    1. AndroidDrawableFactory 一个生成Android应用所需尺寸图片的工具. 托管在Github之中: https://github.com/tizionario/Android ...

  2. 3. Android框架和工具之 xUtils(DbUtils )

    1. xUtils简介 xUtils 包含了很多实用的android工具.xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10种谓 ...

  3. 3. Android框架和工具之 xUtils(BitmapUtils)

    1. BitmapUtils 作用: 加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象: 支持加载网络图片和本地图片: 内存管理使用 ...

  4. 3. Android框架和工具之 xUtils(HttpUtils)

    1. HttpUtils 作用: 支持同步,异步方式的请求: 支持大文件上传,上传大文件不会oom: 支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD请求: 下载支持301/3 ...

  5. 10. Android框架和工具之 AppMsg(消息提示)

    1. AppMsg 优雅的弹出类似Toast的消息提示,支持3种状态Alert(警告),Confirm(确认)以及Info(消息).        2. AppMsg使用: (1)AppMsg下载地址 ...

  6. 7. Android框架和工具之 android-percent-support-lib-sample(百分比支持)

    1. android-percent-support-lib-sample介绍: 谷歌最新的百分比布局库的示例项目.其实LinearLayout的layout_weight也能实现百分比效果,不过这个 ...

  7. 5. Android框架和工具之 ZXing(二维码)

    Android进阶笔记06:Android 实现扫描二维码实现网页登录

  8. 3. Android框架和工具之 xUtils(ViewUtils )

    1. ViewUtils 作用: 完全注解方式就可以进行UI绑定和事件绑定. 无需findViewById和setClickListener等. 2. UI绑定 和 事件绑定 (1)UI绑定 下面我們 ...

  9. Android框架式编程之Android Architecture Components

    1. 当前Android开发面临的问题 Android开发不同于传统的桌面程序开发,桌面程序一般都有唯一的快捷方式入口,并且常作为单进程存在:而一个典型的Android应用通常由多个应用组件构成,包括 ...

  10. 6. Android框架和工具之 JSON解析

    Android进阶笔记17:3种JSON解析工具(org.json.fastjson.gson)

随机推荐

  1. jfinal的ajax例子

    @(编程) 简介 JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful. 在拥有Java语言所有 ...

  2. 解决Windows时间同步失败问题!系统时间同步设置!

    使用NTP协议可以让你的计算机自动与服务器上的时间同步.从而保持最准确的时间. 中国国家授时中心的IP地址是:210.72.145.44 (至少我一直没ping通) 在Windows XP/2000/ ...

  3. FZU 8月有奖月赛A Daxia & Wzc's problem (Lucas)

    Problem A Daxia & Wzc's problem Accept: 42    Submit: 228Time Limit: 1000 mSec    Memory Limit : ...

  4. python sleep

    Python Sleep休眠函数 Python 编程中使用 time 模块可以让程序休眠,具体方法是time.sleep(秒数),其中"秒数"以秒为单位,可以是小数,0.1秒则代表 ...

  5. iOS单例 宏定义

    #define singleton_interface(className) \ + (className *)shared##className; // @implementation #defin ...

  6. MySQL主从复制的原理及配置

    [http://www.jb51.net/article/50053.htm]   MySQL 数据库的高可用性架构:         集群,读写分离,主备.而后面两种都是通过复制来实现的.下面将简单 ...

  7. (4)html表格

    本节解说 :html的表格 表格: *<table></table> 标签定义 HTML 表格. *简单的 HTML 表格由 table 元素以及一个或多个 tr.th 或 t ...

  8. Hadoop ecosystem

    How did it all start- huge data on the web! Nutch built to crawl this web data Huge data had to save ...

  9. mina高并发短连接导致java.io.IOException: Too many open files解决方案

    http://marsvaadin.iteye.com/blog/1698924 mina性能测试 http://hi.baidu.com/rendong/item/bb5d2b0e4563c76dd ...

  10. sql注入在线检測(sqlmapapi)

    之前一搞渗透的同事问我.sqlmapapi.py是干啥的,我猜非常多人都玩过sqlmap,但玩过sqlmapapi的应该比較少,今天就和大家一起看看怎样使用以及一些美的地方. 说白了.sqlmapap ...