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异步回调的. 在做一个项目的时候,上网看了很多别人的例子,发现都没有一个简单的,方便的异步请求的封装例子.我这里要给出的封装代码,是异 ...
随机推荐
- OBIEE 11g 启动与停止包含服务器重启
ORACLE_BIEE_HOME为biee安装路径 注意:默认建立的是"instance1"但是如果你安装过多次可能实例名是不一样(例如: instance2以此类推).因此,请找 ...
- JavaScript Patterns 4.1 Functions Background
Functions are first-class objects and they provide scope. • Can be created dynamically at runtime, d ...
- 关于Redis info的参数总结
Redis官网对 info 已经讲解的比较清楚的,参考文档 .可以看到,info的输出结果是分几块的,有Servers.Clients.Memory等等,通过info后面接这些参数,可以指定输出某一块 ...
- hibernate多对多映射关系实现
Course.hbm.xml: <?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC &q ...
- 启动rabbitmq web管理后台插件
安装完rabbitmq server之后,访问http://server_ip:15672/ 无法打开网页, 通过netstat -ano |grep 15672 查看此端口号并没有开启 需要启用 ...
- POJ 2406 Power Strings (KMP)
Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...
- iTOP-4412开发板低功耗高性能的开源硬件平台——上手评测
iTOP-4412开发板现在比较热门的开发板,笔者近期入了一套.也推荐给初学ARM的朋友学习,4412开发板搭载三星Exynos四核处理器,配备1GB内存,4GB固态硬盘EMMC存储,兼具快速读取与超 ...
- Hive Word count
--https://github.com/slimandslam/pig-hive-wordcount/blob/master/wordcount.hql DROP TABLE myinput; DR ...
- matlab生成HEX文件-任意信号 大于64K长度
HEX文件格式不赘述,写里直接放上代码.请批评改正. %%convert a signal data into hex file format % data format:16bit % signal ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第一,二,三,,四,五章)
SQL - Structured Query Language (结构化查询语言) 1/ SQL 命令的类型 : 数据定义语言: DDL 数据操作语言: DML 数据查询语言: DQL 数据控制语言 ...