Android中的异步网络请求
本篇文章我们来一起写一个最基本的Android异步网络请求框架,借此来了解下Android中网络请求的相关姿势。由于个人水平有限,文中难免存在疏忽和谬误,希望大家可以指出,谢谢大家:)
1. 同步网络请求
以HTTP的GET请求为例,我们来介绍一下Android中一个基本的同步请求框架的实现。直接贴代码:
public class HttpUtils {
public static byte[] get(String urlString) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
//设置请求方法
urlConnection.setRequestMethod("GET");
//设置超时时间
urlConnection.setConnectTimeout(5000);
urlConnection.setReadTimeout(3000);
//获取响应的状态码
int responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream in = urlConnection.getInputStream();
byte[] buffer = new byte[4 * 1024];
int len = -1;
while((len = in.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
close(in);
byte[] result = bos.toByteArray();
close(bos);
return result;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
private static void close(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
相信以上的代码我们大家都不陌生,以上代码就实现了基本的同步网络请求功能,get 方法会返回一个byte[]数组,后续我们可以根据返回的相应类型(文本或图片)对这个字节数组作进一步处理。
2. 异步网络请求
通常一个异步HTTP GET请求是这样的:发出get方法的调用后,相关任务会在后台线程中自动执行,而我们在主线程中继续处理其他工作,它成功获取GET请求的响应时,就会回调onSuccess方法。最直接的写法通常如下所示:
public class AsyncHttpUtils {public static byte[] get(String url, ResponseHandler handler) {
final Handler mHandler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
final byte[] result = HttpUtils.get(url);
handler.post(new Runnable() {
@Override
public void run() {
responseHandler.onSuccess(result);
}
});
}
});
}
}
其中,ResponseHandler接口的定义如下:
public interface ResponseHandler {
void onSuccess(byte[] result);
}
我们可以看到,以上实现异步GET请求的代码很直截了当,然而存在着以下问题:每次请求时都会创建一个线程,这样当请求比较频繁的情况下会创建大量大线程,这样的话创建、销毁线程以及线程调度的开销会很大。而且Thread对象是一个匿名内部类对象,会隐式持有外围类引用,可能会引起Memory Leak。
针对以上问题,我们可以使用线程池来复用线程,以避免不必要的创建及销毁线程的开销,改进后AsyncHttpUtils类的代码如下:
public class AsyncHttpUtils {
//获取当前设备的CPU数
public static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心池大小设为CPU数加1
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
//设置线程池的最大大小
private static final int MAX_POOL_SIZE = 2 * CPU_COUNT + 1;
//存活时间
private static final long KEEP_ALIVE = 5L;
//创建线程池对象
public static final Executor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAX_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
public static void get(final String url, final ResponseHandler responseHandler) {
final Handler mHandler = new Handler(Looper.getMainLooper());
//创建一个新的请求任务
Runnable requestRunnable = new Runnable() {
@Override
public void run() {
final byte[] result = HttpUtils.get(url);
if (result != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
//result不为空表明请求成功,回调onSuccess方法
responseHandler.onSuccess(result);
}
});
}
}
};
threadPoolExecutor.execute(requestRunnable);
}
}
以上代码主要就是使用了线程池来达到线程的复用的目的,关于线程池的更加深入详细的介绍,大家可以看这里:深入理解Java之线程池
3. 参考资料
Android docs
Android中的异步网络请求的更多相关文章
- IOS9中使用NSURLConection发送异步网络请求
IOS9中使用NSURLConection发送异步网络请求 在ios9中,NSURLConection的sendSync..和sendAsync已经过时.被NSURLSession代替. 以下蓝色部分 ...
- Android中AsyncTask异步
今天我们学习了 AsyncTack, 这是一个异步任务. 那么这个异步任务可以干什么呢? 因为只有UI线程,即主线程可以对控件进行更新操作.好处是保证UI稳定性,避免多线程对UI同时操作. 同时要把耗 ...
- Android探索之HttpURLConnection网络请求
前言: 最近一直想着学习一下比较好的开源网络框架okhttp,想着学习之前还是先总结一下Android原生提供的网络请求.之前一直在使用HttpClient,但是android 6.0(api 23) ...
- iOS 多个异步网络请求全部返回后再执行具体逻辑的方法
对于dispatch多个异步操作后的同步方法,以前只看过dispatch_group_async,看看这个方法的说明: * @discussion * Submits a block to a dis ...
- AJAX其实就是一个异步网络请求
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).其实就是一个异步网络请求. 一.创建对象 var xmlhttp; if (w ...
- Android Asynchronous Http Client-Android异步网络请求客户端接口
1.简介 Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnect,但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求,而使用and ...
- Android之封装好的异步网络请求框架
1.简介 Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnection,但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求,而使 ...
- Android中android-async-http开源网络框架的简单使用
android-async-http开源网络框架是专门针对Android在Apache的基础上构建的异步且基于回调的http client.所有的请求全在UI线程之外发生,而callback发生在创建 ...
- iOS开发——post异步网络请求封装
IOS中有许多网络请求的函数,同步的,异步的,通过delegate异步回调的. 在做一个项目的时候,上网看了很多别人的例子,发现都没有一个简单的,方便的异步请求的封装例子.我这里要给出的封装代码,是异 ...
随机推荐
- iphone,pad等真机不被xcode识别,解决方法
问题现象:xcode 的项目在进行真机调试时,xcode不能识别真机, 调测情况分析: 1 设备正常,itunes 能够识别 2 在apple developer 中创建项目的Provisioning ...
- java基础-在dos控制台编写简易 的java程序
第一步:在文件夹中修改隐藏的文件扩展名,让其文件的扩展名全部显示:————win7系统在文件的组织下方的文件夹和搜索选项,选择查看,将里面的隐藏选项取消: 第二步:在文件夹中新建一个text文件,将其 ...
- 【整理贴】DBA-常用到的动态视图分析语句
测试应用环境:SQL2008 R2.SQL2012.SQL2014 --语句1:获取前20逻辑读取次数或逻辑写入次数或CPU 时间 SELECT TOP 20 SUBSTRING(qt.TEXT, ( ...
- Report List Controls
Report风格的ListCtrl的扩展,原文链接地址:http://www.codeproject.com/Articles/5560/Another-Report-List-Control 1.列 ...
- web开发相关解决方案
HTML5 API 应用 History.js - gracefully supports the HTML5 History/State APIs pushState + ajax Notify.j ...
- 用shell脚本写一个for循环
一.输出十遍北京 for((i=1;i<10;i++))> do> echo '北京';> done 二.死循环 for((;;))do#java -jar producer. ...
- mysql table 最新更新时间
查看表的最后mysql修改时间 SELECT TABLE_NAME,UPDATE_TIME FROM information_schema.tables where TABLE_SCHEMA='d ...
- vs安装mvc
需要一个MVC框架和SP1补丁包,SP1补丁包的下载地址为:http://www.microsoft.com/downloads/details.aspx?FamilyID=27673c47-b3b5 ...
- django安装和卸载
一.pip安装 安装: apt-get update apt-get install python-pip pip install django==1.4.20 卸载: pip uninstall d ...
- OpenXml入门----给Word文档添加表格
下面将展示如何使用Openxm向Word添加表格. 代码中表头和数据我用的同一个TableRow来添加,其实可以通过TableHeader来,其实都一样.后面教程我会给出如何设置单元格样式.表头那一行 ...