async-http-client开源库学习笔记(一)

0. 文前闲话

作为一个Android开发的大龄初学者,面对扑面而来的各种姿势的Android的开源组件,让人倍感窒息,难以应对。无奈为了养家糊口,虽然已近不惑,人老珠黄,也只能废寝忘食,逐个体位细细揣摩研究,不断以身实践,争取早日小成。

话说那是一个阳光明媚的下午,我坐在街口转角处优雅的网络会所里,品着一杯上好的Coca-Cola,研读着oschina客户端源码,身旁不时传来:“一起上搞死他,他没蓝了...!”。

从火蚁(oschina客户端的开发者之一,向他们致敬)那里知道了async-http-client开源库,为了千千万万个没过英语四级的程序猿GG,就在这里翻译个作者写的"用户说明书"先...

1. async-http-client开源库简介

async-http-client库是一个基于回调函数的Http异步通信客户端Android组件,在Apache的HttpClient库的基础上开发构建而成的。这里的异步,是指它所有的网络请求都是在app的主界面线程之外的独立工作线程中执行。通过使用Android的消息处理机制,它所有的回调函数却又是在这个回调函数的创建线程中执行的。除了应用在开发普通App之外,如果你用在开发Service或后台线程时,Asynchronous Http Client库可以自动识别是被用在哪一种环境下。

1.1 特点

  • 异步方式发起Http请求,可以使用匿名回调函数处理网络应答;
  • 在UI主线程之外的工作线程发起Http请求;
  • 通过使用线程池解决了资源并发的效率问题;
  • 通过使用RequestParams类,可完成GET/POST的参数构建
  • 支持文件的分段下载功能;
  • 支持上传JSON数据流
  • 对重定向循环、重定向相对路径异常进行了处理
  • 代码体积小,全部功能只占90kb;
  • 专门针对移动网络的不稳定性,对请求重发进行了优化,实现了自动智能处理;
  • 传输时支持数据压缩,可自动对应答进行gzip解压处理;
  • 使用BinaryHttpResponseHandler,可进行较底层的tcp/ip协议数据通信;
  • JsonHttpResponseHandler内嵌JSON语法分析功能,可完成JSON数据解析;
  • FileAsyncHttpResponseHandler可直接将应答保存到本地文件中;
  • 支持cookie的持久化,可使用App的SharedPreferences保存cookie信息;
  • 通过BaseJsonHttpResponseHandler可与Jackson JSON, Gson等第三方JSON框架库集成;
  • SaxAsyncHttpResponseHandler支持SAX语法分析
  • 除了UTF-8,还支持其它语言编码。

1.2 使用async-http-client的大型应用

  • Instagram
  • Pinterest
  • Frontline Commando (Glu Games)
  • Heyzap
  • Pose

(以上应用我一个都没用过,反正说明async-http-client很diao就对了)

2. async-http-client库的安装和基本应用

2.1 基本应用方法

1. 在Gradle build脚本中增加

dependencies {
    compile ‘com.loopj.android:android-async-http:1.4.8‘
}

2. 引入http包

import com.loopj.android.http.*;

3. 创建AsyncHttpClient 实例,并发出请求

AsyncHttpClientclient = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler(){
    @Override
    public void onStart(){
        // called before request is started
    }
    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response){
        // called when response HTTP status is "200 OK"
    }
    @Override
    public void onFailure(int statusCode, Header[] headers,
                          byte[] errorResponse, Throwablee){
        // called when response HTTP status is "4XX" (eg. 401, 403, 404)
    }
    @Override
    public void onRetry(int retryNo){
        // called when request is retried
    }
});

2.2 推荐使用方法:创建静态Http客户端

创建AsyncHttpClient的静态实例进行通信更加方便,以使用Twitter提供的Api为例(此处使用Twitter作例子,站在大墙里面的我们看看就行了):

import com.loopj.android.http.*;

public class TwitterRestClient {
    private static final String BASE_URL = "https://api.twitter.com/1/";

    private static AsyncHttpClient client = new AsyncHttpClient();

    public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
        client.get(getAbsoluteUrl(url), params, responseHandler);
    }

    public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
        client.post(getAbsoluteUrl(url), params, responseHandler);
    }

    private static String getAbsoluteUrl(String relativeUrl) {
        return BASE_URL + relativeUrl;
    }
}

TwitterRestClient 类中创建了一个AsyncHttpClient的静态实例,通过静态实例与Twitter进行数据通信,共有两个对外的接口函数get,set,也都是静态的。下面是如何在代码中使用这个类:

import org.json.*;
import com.loopj.android.http.*;

class TwitterRestClientUsage {
    public void getPublicTimeline() throws JSONException {
        TwitterRestClient.get("statuses/public_timeline.json", null, 
                new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, 
                    JSONObject response) {
                // If the response is JSONObject instead of expected JSONArray
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, 
                    JSONArray timeline) {
                // Pull out the first event on the public timeline
                JSONObject firstEvent = timeline.get(0);
                String tweetText = firstEvent.getString("text");

                // Do something with the response
                System.out.println(tweetText);
            }
        });
    }
}

这里使用了匿名回调函数,并且是JsonHttpResponseHandler类型,它内嵌了Json语言解析器,可直接在处理函数中使用对应答数据解析后的Json数据,真是即方便又快捷。

3. 使用PersistentCookieStore进行Cookie的持久化存储

async-http-client库包含一个PersistentCookieStore类,这个类实现了CookieStore接口(源自Apache HttpClient包),可自动将cookie信息保存到应用的SharedPreferences储存中。

如果你的应用需要使用cookie维护用户授权session,这是非常有用,方便的。即使关闭了app或重新启动app,应用也可以保持用户已登录的状态。

首先创建一个AsyncHttpClient实例:

AsyncHttpClient myClient = new AsyncHttpClient();

为这个实例设置一个新建的PersistentCookieStore的实例以进行cookie存储,调用这个PersistentCookieStore实例的构造函数时,使用一个activity或application context作参数(一般用this就可以了):

PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
myClient.setCookieStore(myCookieStore);

这样由服务端接收到的cookie将会自动存储在你的android设备上。如果要添加自己的cookie,只需要构建一个新的cookie并调用addCookie函数:

BasicClientCookie newCookie = new BasicClientCookie("cookiesare", "awesome");
newCookie.setVersion(1);
newCookie.setDomain("mydomain.com");
newCookie.setPath("/");
myCookieStore.addCookie(newCookie);

4. 使用RequestParams增加GET/POST参数

4.1 为请求增加参数

大部分应用的url请求都需要带各种参数,在Get/Post请求时增加参数,可使用RequestParams类。

可以使用以下三种方法构建RequestParams实例:

1. 创建一个空的RequestParams实例,并增加参数:

RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");

2. 只有一个参数,创建RequestParams实例:

RequestParams params = new RequestParams("single", "value");

3. 利用已存在的Map键值对创建RequestParams实例:

HashMap<String, String> paramMap = new HashMap<String, String>();
paramMap.put("key", "value");
RequestParams params = new RequestParams(paramMap);

4.2 利用RequestParams上传文件

RequestParams类还可以用来实现文件分段上传,有以下三种实现方式:

1. 将InputStream作为参数加入RequestParams:

InputStream myInputStream = blah;
RequestParams params = new RequestParams();
params.put("secret_passwords", myInputStream, "passwords.txt");

2. 直接将File对象增加到RequestParams中:

File myFile = new File("/path/to/file.png");
RequestParams params = new RequestParams();
try {
    params.put("profile_picture", myFile);
} catch(FileNotFoundException e) {}

3. 使用二进制字节数组:

byte[] myByteArray = blah;
RequestParams params = new RequestParams();
params.put("soundtrack", new ByteArrayInputStream(myByteArray), "she-wolf.mp3");

5. 使用FileAsyncHttpResponseHandler下载二进制数据

FileAsyncHttpResponseHandler用来获取二进制数据,比如图像、声音等文件。

AsyncHttpClient client = new AsyncHttpClient();
client.get("https://example.com/file.png", 
        new FileAsyncHttpResponseHandler(/* Context */ this) {
    @Override
    public void onSuccess(int statusCode, Header[] headers, File response) {
        // Do something with the file `response`
    }
});

6. 为HTTP通信增加授权认证

在实际应用环境中,某些服务器资源需要用户名/密码授权认证才能访问,这类资源访问需要使用HTTP Basic Access Authentication协议,请求才能被处理。可以使用setBasicAuth函数提供认证信息。

为主机或域名访问设置用户名/密码,默认状态认证信息对所有主机、端口或域名有效。

AsyncHttpClient client = new AsyncHttpClient();
client.setBasicAuth("username","password/token");
client.get("https://example.com");

更为推荐的方式是对特定的主机或端口提供授权认证信息:

AsyncHttpClient client = new AsyncHttpClient();
client.setBasicAuth("username","password", 
        new AuthScope("example.com", 80, AuthScope.ANY_REALM));
client.get("https://example.com");
时间: 2024-08-30 06:22:50

async-http-client开源库学习笔记(一)的相关文章

0806------Linux网络编程----------Echo 网络库 学习笔记

1.Echo网络库的编写 1.1 Echo网络库1.0 1.1.1 Echo网络库 1.0 框架分析 a)class InetAddress: 主要用来定义一个struct sockaddr_in 结构(用自定义端口号初始化),并提供获取这个结构体成员如IP.Port等的接口: b)class Socket : 主要用来把一个普通的 sockfd 变为 listenfd(这里用一个sockfd初始化对象),提供bind .listen.accept 等接口. c)class TcpConnect

初探boost之timer库学习笔记

timer 用法 #include <boost/timer.hpp> #include <iostream> using namespace std; using namespace boost; int main() { timer t;//声明一个计时器对象,开始计时 cout<<"max:"<<t.elapsed_max()/3600<<"h"<<endl; //可度量的最大时间,以小时

初探boost之progress_display库学习笔记

progress_display 用途 progress_display可以在控制台上显示程序的执行进度,如果程序执行很耗费时间,那么它能提供一个友好的用户界 面,不至于让用户在等待中失去耐心,甚至怀疑程序的运行是否出了问题. 用法示例 #include <boost/progress.hpp> #include <iostream> #include <vector> using namespace std; using namespace boost; int ma

初探boost之smart_ptr库学习笔记

概述 Boost.smart_ptr库提供了六种智能指针,除了shared_ptr 和 weak_ptr 以外还包括 scoped_ptr .scoped_array . shared_array .intrusive_ptr .他们的速度与原始指针相差无几,都是异常安全的,而且对于类型T也仅有一个要 求:类型T的析构函数不能抛出异常. 使用时包含头文件: #include<boost/smart_ptr.hpp> scoped_ptr 用法: scoped_ptr 的构造函数接受一个类型为T

Java 8 流库学习笔记(一)

[core Java学习笔记]Java SE8 流库 Stream Library 从迭代到流 如果要计算一个文本中有多少长单词(字母>12). 迭代式: words = getlist();//虚构方法,获得一个List<String> long count = 0; for(String w:words) { if(w.length()>12) count++; } 流式: words = getlist();//虚构方法,获得一个List<String> long

Lufylegend库学习笔记1 绘图操作及鼠标事件

这几天对于网页前端有点兴趣,学习了一下Canvas的相关知识. 看到Lufylegend库之后,感觉很棒,有一种在写AS的感觉.今天入门第一站,写了一个画板. 是一个非常简易的画板,但是可以看到一些重要的思想. 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Mouse Event</title&g

GDAL库学习笔记(1):无缝拼接Google卫星图

开工之前要先了解一下瓦片地图,瓦片地图金字塔模型是一种多分辨率层次模型,从瓦片金字塔的底层到顶层,分辨率越来越低,但表示的地理范围不变.实现原理就是,首先确定地图服务平台所要提供的缩放级别的数量N,把缩放级别最低.地图比例尺最大的地图图片作为金字塔的底层,即第0层,并对其进行分块,从地图图片的左上角开始,从左至右.从上到下进行切割,分割成相同大小(比如256x256像素)的正方形地图瓦片,形成第0层瓦片矩阵;在第O层地图图片的基础上,按每2x2像素合成为一个像素的方法生成第1层地图图片,并对其进

第三方开源库学习

https://github.com/syedhali/EZAudio基于核心音频,有助于进行实时,低延迟音频处理和可视化的iOS和OSX音频可视化框架. https://github.com/bang590/JSPatchJSPatch使用Objective-C运行时桥接Objective-C和Javascript.你可以只包括一个此库,就可以通过JavaScript调用Objective-C中的任何类和方法. JSPatch一般用于动态修复iOS应用程序. https://github.co

python requests库学习笔记(上)

尊重博客园原创精神,请勿转载! requests库官方使用手册地址:http://www.python-requests.org/en/master/:中文使用手册地址:http://cn.python-requests.org/zh_CN/latest/: requests库作者Kenneth Reitz个人主页:https://www.kennethreitz.org/: requests库github地址:https://github.com/requests/requests: requ