快速Android开发系列网络篇之Android-Async-Http-程序员宅基地

技术标签: ui  移动开发  数据库  

先来看一下最基本的用法

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
    @Override
    public void onSuccess(String response) {
        System.out.println(response);
    }
});

通过AsyncHttpClient类的实例就可以执行网络请求,包括get、put、post、head、delete。并指定一个ResponseHandlerInterface的实例接收请求结果。(onSuccess参数不对,此处只说明基本用法,详细参数看源码)

主要类介绍

  • 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方法。

请求流程

  1. 调用AsyncHttpClient的get或post等方法发起网络请求
  2. 所有的请求都走了sendRequest,在sendRequest中把请求封装为了AsyncHttpRequest,并添加到线程池执行
  3. 当请求被执行时(即AsyncHttpRequest的run方法),执行AsyncHttpRequest的makeRequestWithRetries方法执行实际的请求,当请求失败时可以重试。并在请求开始,结束,成功或失败时向请求时传的ResponseHandlerInterface实例发送消息
  4. 基本上使用的都是AsyncHttpResponseHandler的子类,调用其onStart,onSuccess等方法返回请求结果

详细使用方法

官方建议使用一个静态的AsyncHttpClient,像下面的这样:

public class TwitterRestClient {
    private static final String BASE_URL = "http://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;
    }
}

封装的方法建议都加上Context参数,以在Activity pause或stop时取消掉没用的请求。

详细使用方法就不说了,直接看官方文档

其他说明及总结

Android-Async-Http的使用非常简单,通过AsyncHttpClient发起请求就可以了,如果需要添加参数,直接传一个RequestParams过去,而且参数可以是String、File和InputStream,可以很方便地上传文件。

每个请求都需要传一个ResponseHandlerInterface的实例用以接收请求结果或请求失败,请求结束等通知,一般是AsyncHttpResponseHandler的子类。

通过BinaryHttpResponseHandler可以发起二进制请求,如请求图片。

通过TextHttpResponseHandler可以发起返回结果为字符串的请求,一般这个使用较多。

也可以使用它的子类JsonHttpResponseHandler,返回结果是一个JSONObject或JSONArray。不过感觉这个类作用不大,一是有另一个类BaseJsonHttpResponseHandler,可以直接解析返回的JSON数据,二是JsonHttpResponseHandler的方法太复杂了,有太多的onSuccess和onFailure方法,都不知道重写哪个了。

如上图所示,每个子类有太多的onSuccess和onFailure了,尤其是JsonHttpResponseHandler,这应该算是这个类库的不足吧。所以平时使用时基本不使用JsonHttpResponseHandler,而是直接使用TextHttpResponseHandler,当然也可以使用BaseJsonHttpResponseHandler。

这个类库还有一点不足,就是onSuccess等方法一般会在主线程执行,其实这么说不严谨,看代码吧:

public AsyncHttpResponseHandler() {
    boolean missingLooper = null == Looper.myLooper();
    // Try to create handler
    if (!missingLooper)
        handler = new ResponderHandler(this);
    else {
        // There is no Looper on this thread so synchronous mode should be used.
        handler = null;
        setUseSynchronousMode(true);
        Log.i(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode.");
    }
    // Init Looper by calling postRunnable without an argument.
    postRunnable(null);
}

可以看到,内部使用了Handler,当新建AsyncHttpResponseHandler的实例的时候会获取当前线程的Looper,如果为空就启用同步模式,即所有的回调都会在执行请求的线程中执行,当在一个普通的后台线程时这样执行是正常的,而我们一般都会在主线程发请请求,结果就是所有的回调都会在主线程中执行,这就限制了我们在onSuccess中执行耗时操作,比如请求成功后将数据持久化到数据库。

不过可以看到创建Handler的时候使用了Looper对象,所以我们就可以改进一下其构造函数,添加一个Looper参数(同步修改子类),这样所有的回调就都会在Looper所在线程执行,这样我们只需要开启一个HandlerThread就行了。但这样和Looper为空时一样有一个弊端,如果要更新UI操作的话,还需要向一个主线程的Handler发送消息让UI更新。还有第二个弊端,所有回调都在同一个HandlerThread中执行,如果一个处理耗时太久会阻塞后面的请求结果处理,如果只是简单地写个数据库影响应该不大,如果真耗时太久,为这个耗时处理再开个线程吧。

 

转载于:https://www.cnblogs.com/angeldevil/p/3729808.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/aehvbew8628/article/details/102433609

智能推荐

cnn图像二分类 python_人工智能Keras图像分类器(CNN卷积神经网络的图片识别篇)...-程序员宅基地

文章浏览阅读1k次。上期文章我们分享了人工智能Keras图像分类器(CNN卷积神经网络的图片识别的训练模型),本期我们使用预训练模型对图片进行识别:Keras CNN卷积神经网络模型训练导入第三方库from keras.preprocessing.image import img_to_arrayfrom keras.models import load_modelimport numpy as npimport i..._二分类图像检测python

MySQL数据导入 : ERROR 1290 (HY000) 错误解决方案_error 1290(hy000)导入数据-程序员宅基地

文章浏览阅读1w次,点赞5次,收藏16次。想要导入文件进mysql里面的数据表,执行LOAD DATA INFILE '/Users/ziqi.zhang/testDB.csv' INTO TABLE goods FIELDS TERMINATED BY ',';返回:ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option..._error 1290(hy000)导入数据

linux 去掉csv文件第一行,使用PowerShell删除文本文件的第一行-程序员宅基地

文章浏览阅读907次。使用PowerShell删除文本文件的第一行我试图在导入它们之前删除大约5000个文本文件的第一行。我对PowerShell还是很陌生,因此不确定要搜索什么或如何进行此操作。 我当前使用伪代码的概念:set-content file (get-content unless line contains amount)但是,我似乎无法弄清楚如何执行包含操作。Buddy Lindsey asked 20..._powershell 去掉csv第一行

c语言式贪吃蛇为什么有按键延迟,请教一个C语言贪吃蛇问题:为什么运行结果是蛇的长度在增加啊?...-程序员宅基地

文章浏览阅读370次。已结贴√问题点数:20回复次数:3 请教一个C语言贪吃蛇问题:为什么运行结果是蛇的长度在增加啊?我第一步只是编写一个简单的,没有食物,蛇也不增长,只是用上下左右四个键控制蛇的运动,蛇碰壁就退出。程序的算法就是蛇头的坐标根据方向而加减10,而蛇段的坐标则依次等于前面一节蛇段的坐标,然后把蛇尾黑掉(setcolor(0)),这样就实现了蛇的运动,但是问题是程序运行后,结果是蛇在不断地增长,这是怎么..._贪吃蛇小游戏为什么按下按键之后1秒才有反应

十八、jasperreport导出word,excel,pdf_jasper生成word-程序员宅基地

文章浏览阅读1.3k次。十八、jasperreport导出word,excel,pdfpackage output;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.OutputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLExcepti_jasper生成word

python怎么读excel_如何使用xlrd和python读取excel表格内容以及其他格式信息,然后简单输出...-程序员宅基地

文章浏览阅读170次。1 #!/usr/bin/env python2 3 ###file:xlrdT3a.py4 5 classreadexcel(object):6 """Simple OS Independent Class for Extracting Data from Excel Files7 the using xlrd module found at http://www.lexicon.net/sjm..._if(self.row_range)

随便推点

【keras】GoogleNet 网络结构及其实现_keras.model googlenet-程序员宅基地

文章浏览阅读6k次,点赞2次,收藏20次。深度学习模型常常通过增加模型的深度或者宽度来获得更高的性能。本文将就深度学习常见的网络结构进行介绍。GoogLeNet是2014年Christian Szegedy提出的一种全新的深度学习结构,在这之前的AlexNet、VGG等结构都是通过增大网络的深度来获得更好的训练效果,但层数的增加会带来很多负作用,比如overfit、梯度消失、梯度爆炸等。在介绍GoogLeNet之前,先介绍一下两种..._keras.model googlenet

0、如何用运python成为顶级黑客_python代码黑客访问-程序员宅基地

文章浏览阅读1k次,点赞5次,收藏9次。Python编程语言在网络安全工作中具有许多优势,以下是一些详细介绍:1. 简洁易学:Python语法简单、清晰,易于理解和学习。这使得初学者能够快速上手,并且能够快速开发出功能强大的网络安全工具。2. 大量的库和框架:Python拥有丰富的第三方库和框架,如Scapy、Requests、BeautifulSoup等,这些库和框架提供了丰富的功能和工具,方便开发人员进行网络安全相关的任务,如网络扫描、漏洞检测、数据分析等。_python代码黑客访问

计算机毕设(附源码)JAVA-SSM连锁便民超市前端系统-程序员宅基地

文章浏览阅读433次。项目运行环境配置:(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可4.

SpringBoot项目打包部署到阿里云服务器、通过Maven插件制作Docker镜像、部署项目容器、配置生产环境_spring-boot-starter-web 在阿里哪个仓-程序员宅基地

文章浏览阅读1k次,点赞8次,收藏7次。SpringBoot项目打包部署到阿里云服务器、通过Maven插件制作Docker镜像、部署项目容器、配置生产环境_spring-boot-starter-web 在阿里哪个仓

精通数据库可以从事什么工作_是的,您也可以开始从事数据科学-程序员宅基地

文章浏览阅读1k次。精通数据库可以从事什么工作A short guide on how to get started in the wonderful world of data science关于如何在数据科学的美好世界中入门的简短指南Machine Learning, Artificial Intelligence, Neural Networks, Python, … If you’re somewhat i..._专精数据库能找到工作吗

rep汇编指令_汇编语言中repne-程序员宅基地

文章浏览阅读2.7w次,点赞2次,收藏38次。REP/REPE/REPZ/REPNE/REPNZ - 重复字符串操作前缀操作码指令说明F3 6CREP INS r/m8, DX将 (E)CX 个字节从端口 DX 输入到 ES:[(E)DI]F3 6DREP INS r/m16,DX将 (E)CX 个字从端_汇编语言中repne

推荐文章

热门文章

相关标签