Android HTTP网络请求的异步实现
作者:lijiao 发布时间:2022-05-12 09:35:39
前言
大家都知道网络操作的响应时间是不定的,所有的网络操作都应该放在一个异步操作中处理,而且为了模块解耦,我们希望网络操作由专门的类来处理。所有网络数据发送,数据接收都有某几个类来实现,外部其它模块只要调用和处理回调函数即可。外部模块和网络模块之间的调用关系可以用如下图表示:
调用端只要创建Request对象,设置参数,发起请求,即可。最后结果通过回调函数返回。右边的异步任务,HttpClient创建,参数解析,错误处理全部交给网络处理模块来完成。由此来看,这个网络模块其实是重复性很高的开发工作,为了避免重复造轮子,下面就给大家介绍下我们工作中实现的网络操作模块及相应类的实现。
1.调用端代码:
Get或Post请求
protected void doWebTest()
{
String url = "http://www.target.com/abcd";
try {
MyHttpRequest http = new MyHttpRequest(url);
//如果是Post请求,则设置.如果是get请求,请不要设置post参数
//http.addPost("data", "testpostvalue");
//post参数结束,get请求,不要添加上面addPost代码
http.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
http.addHeader("Accept-Encoding", "gzip, deflate, sdch");
http.addHeader("Accept-Language","zh-CN,zh;q=0.8");
http.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36");
http.StartRequest(new INetResponseListener() {
@Override
public void OnRequestComplete(NetResponse result) {
if(result.isSuccess())
{
String resultStr = result.resultStr;
//resultStr就是网络返回的数据
}else
{
Exception ee = result.getException();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
以上是调用端需要实现的源码,是不是很少代码就可以完成网络请求?下面就为大家揭开这个网络处理类的面纱。
2.主要类介绍
1.AbstractRequester:一个抽象的网络请求类
2.MyHttpRequest::实例化的网络请求类。如果开发者有其它特殊处理需求,可以继承AbstractRequester 自己重新实现parseResponse
3.HttpEngine:HttpClient网络引擎类,最终的网络请求由这个类处理
4.HttpRequestData:传递给AsyncTask的参数类
5.NetResponse:返回给调用者的响应类
6.INetResponseListener:异步回调的interface
类之间的关系如下图所示:
2.1 AbstractRequester
抽象的网络管理类,类定义如下:
public abstract class AbstractRequester extends AsyncTask<HttpRequestData,Integer,NetResponse> {
...
/**
* 根据需求创建传递给http发送的参数
* @return
*/
abstract HttpRequestData createData();
/**
* 根据返回的流,解析生成相应的对象
* @param in
* @return
*/
abstract NetResponse parseResponse(InputStream in);
//执行完成后的回调函数
protected void onPostExecute(NetResponse result) {
super.onPostExecute(result);
if(listener!=null)
{
listener.OnRequestComplete(result);
}
}
//网络请求开始处理
protected NetResponse doInBackground(HttpRequestData... reqArgs) {
//因内容比较多。具体查看源码
}
public void StartRequest(INetResponseListener aListener){
//具体查看源码
}
}
对于一些有其它特殊需求的开发者,只需要继承这个类,并实现它的抽象接口,如果是通用需求,则可以直接使用下面的MyHttpRequest类:
abstract HttpRequestData createData();
abstract NetResponse parseResponse(InputStream in);
2.2 MyHttpRequest
继承并实现了AbstractRequester的网络处理类,支持Get和Post类型,支持自定义添加headers参数。
对于普通的网络请求和返回已经够用,开发者可以直接使用。
2.3 HttpEngine
网络请求引擎类。主要流程如下:
1.创建createHttpClient
2.判断参数有效性
3.判断get或post
4.创建对应的HttpGet或HttpPost
5.设置各类参数
6.调用httpClient.execute执行网络请求
7.解析和判断网络返回结果
8.生成Stream对象并返回
2.4 HttpRequestData
传递给AsyncTask的参数类,用于设置http请求的各类参数。
2.5 NetResponse
返回给调用者的类对象,包括状态、数据和异常。
2.6 INetResponseListener
定义很简单,源码如下:
public interface INetResponseListener {
/**
* 网络请求返回
* @param result
*/
public void OnRequestComplete(NetResponse result);
}
调用者只要实现这个interface,异步接收返回结果即可,返回结果就是NetResponse对象。
- 常见问题
1. AsyncTask说明
大家都知道AsyncTask是异步的,所以网络请求通过AsyncTask来实现,通过AyncTask的好处是轻量级异步,而且可以操作ui线程,比如更新进度条等。但AsyncTask也存在以下一些问题:
•task需要在ui线程中创建和启用,所以AbstractRequester 对象的创建和调用StartRequest请在ui线程中完成
•API 11也就是3.0以后,AsyncTask是排队执行,所以如果其中一个任务出现较耗时,其它网络请求需要等待;如果你想同步执行,要修改execute为executeOnExecutor(但不推荐做这个修改)
2. 权限
在xml中添加网络操作权限:
<uses-permission android:name="android.permission.INTERNET" />
猜你喜欢
- 前提前面写过一篇关于Environment属性加载的源码分析和扩展,里面提到属性的占位符解析和类型转换是相对复杂的,这篇文章就是要分析和解读
- 本文实例讲述了Java采用循环链表结构求解约瑟夫问题的方法。分享给大家供大家参考。具体分析如下:这是第一次java考试的试题,对于没看过链表
- SpringMVC * path路径的坑SpringMVC提供了很方便的 * 供我们开发使用。在配置文件中通过<mvc:mapping
- 第一种方法string s=abcdeabcdeabcde;string[] sArray=s.Split('c') ;fo
- 前言有位朋友,某天突然问东哥:在 Java 中,防止重复提交最简单的方案是什么?这句话中包含了两个关键信息,第一:防止重复提交;第二:最简单
- Annotation(注解)是JDK1.5及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以&
- 只能输入数字:"^[0-9]*$"。只能输入n位的数字:"^\d{n}$"。只能输入至少n位的数字:
- 本文实例讲述了C#使用XML序列化操作菜单的方法。分享给大家供大家参考。具体分析如下:之前的一篇文章《C#递归读取XML菜单数据的方法》没使
- 这个导出网站功能指通过前台javascript触发进入ashx函数中,实现将服务器中某个文件夹(包含其子文件夹和文件)通通复制到服务器中另一
- 为什么需要网关呢?我们知道我们要进入一个服务本身,很明显我们没有特别好的办法,直接输入IP地址+端口号,我们知道这样的做法很糟糕的,这样的做
- 仿Keep运动休息倒计时控件,供大家参考,具体内容如下源码控件本身非常非常简单,唯一难点在于倒计时期间动态增减时长,如果说动态增减时长是瞬间
- 什么是JWT,它是一种对API的保护方案,为什么要进行保护呢防泄漏:你肯定不希望你的数据能被别人随意调用,比如公司的机密信息,不可能每个人都
- The error simply says, “you've made changes in files in your works
- 本文实例讲述了Android数据持久化之File机制。分享给大家供大家参考,具体如下:在使用Java SE平台开发C/S结构的软件中,Fil
- 详解Java对象的强、软、弱和虚引用+ReferenceQueue一、强引用(StrongReference)强引用是使用最普遍的引用。如果
- 在对接第三方支付的时候,第三方会要求参数按照ASCII码从小到大排序。如下:public static void requestPay()
- Java中字符串中子串的查找共有四种方法(indexof()) indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始
- 由 CardLayout 类实现的布局管理器称为卡片布
- 关于这个系列里的问题,每个学Java的人都应该搞懂。当然,若是仅仅学Java玩玩就无所谓了。若是你以为本人现已逾越初学者了,却不很懂这些问题
- jdk1.8中的for循环jdk1.8 从语法角度,感觉发生的变化还是蛮大的。在此记录一下。for 循环 public stati