Android有两套http的API,刚开始使用网络编程时多少有些迷惑到底用哪个好呢?其实孰优孰劣无需再争论,google已经指出HttpUrlConnection是Android更优的选择,并在SDK文档中引用了博客(需要代理访问)http://android-developers.blogspot.com/2011/09/androids-http-clients.html来阐述各自的优缺点。国内也有些博客大致翻译了上面的内容,并对了一些测试,可惜测试不严密,某博客甚至得出HttpUrlConnection的下载速度快几倍的结论,其实并没有公平反映出二者的下载速度。

  虽然我已经使用过HttpUrlConnection实现了一个轻量级http引擎用于下载,但是好奇心还是促使我写了一个测试程序用于比较二者的性能。由于HttpClient仅仅是一个接口,所以我选用了其实现类DefaultHttpClient和HttpUrlConnection做比较,方法很简单,分别下载同一个文件10次,然后计算耗时的平均值,测试代码片段如下:

     @Override
public void onClick(View v)
{
if (v.equals(mTestHttpClientBtn))
{
new Thread(new Runnable()
{
@Override
public void run()
{
long averageTime = 0;
for (int i = 0; i < 10; i++)
{
File file = new File(getFilesDir(), String.valueOf(i) + ".file");
FileOutputStream fileOutputStream = null;
try
{
fileOutputStream = new FileOutputStream(file);
}
catch (FileNotFoundException e)
{
Log.e(TAG, "", e);
return;
} long startTime = System.currentTimeMillis();
testHttpClient(fileOutputStream);
long stopTime = System.currentTimeMillis(); averageTime += stopTime - startTime;
}
averageTime /= 10; // 测试完成
Message msg = new Message();
msg.what = MSG_TEST_HTTP_CLIENT_DONE;
msg.obj = averageTime;
mHandler.sendMessage(msg);
}
}).start(); return;
} if (v.equals(mTestHttpUrlConnectionBtn))
{
new Thread(new Runnable()
{
@Override
public void run()
{
long averageTime = 0;
for (int i = 0; i < 10; i++)
{
File file = new File(getFilesDir(), String.valueOf(i + 10) + ".file");
FileOutputStream fileOutputStream = null;
try
{
fileOutputStream = new FileOutputStream(file);
}
catch (FileNotFoundException e)
{
Log.e(TAG, "", e);
return;
} long startTime = System.currentTimeMillis();
testHttpUrlConnection(fileOutputStream);
long stopTime = System.currentTimeMillis(); averageTime += stopTime - startTime;
}
averageTime /= 10; // 测试完成
Message msg = new Message();
msg.what = MSG_TEST_HTTP_URL_CONNECTION_DONE;
msg.obj = averageTime;
mHandler.sendMessage(msg);
}
}).start(); return;
}
} private void testHttpClient(FileOutputStream fileOutputStream)
{
DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity entity = null;
InputStream inputStream = null;
try
{
HttpGet httpGet = new HttpGet(TEST_URL);
HttpResponse httpResponse = httpClient.execute(httpGet); StatusLine statusLine = httpResponse.getStatusLine();
if (statusLine == null)
{
throw new Exception("no status line !!!");
}
int responseCode = statusLine.getStatusCode();
if (responseCode < 200 || responseCode >= 300)
{
throw new Exception("response error !!!");
}
entity = httpResponse.getEntity();
if (entity == null)
{
throw new Exception("no entity !!!");
}
inputStream = entity.getContent();
int bytesRead = -1;
byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1)
{
fileOutputStream.write(buffer, 0, bytesRead);
}
}
catch (Exception e)
{
Log.e(TAG, "", e);
}
finally
{
try
{
if (inputStream != null)
{
inputStream.close();
} if (entity != null)
{
entity.consumeContent();
} if (fileOutputStream != null)
{
fileOutputStream.flush();
fileOutputStream.close();
}
}
catch (Exception e)
{
Log.e(TAG, "", e);
}
}
} private void testHttpUrlConnection(FileOutputStream fileOutputStream)
{
HttpURLConnection httpURLConnection = null;
InputStream inputStream = null;
try
{
httpURLConnection = (HttpURLConnection) new URL(TEST_URL).openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect(); int responseCode = httpURLConnection.getResponseCode();
if (responseCode < 200 || responseCode >= 300)
{
throw new Exception("response error !!!");
}
inputStream = httpURLConnection.getInputStream();
int bytesRead = -1;
byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1)
{
fileOutputStream.write(buffer, 0, bytesRead);
}
}
catch (Exception e)
{
Log.e(TAG, "", e);
}
finally
{
try
{
if (inputStream != null)
{
inputStream.close();
} if (httpURLConnection != null)
{
httpURLConnection.disconnect();
} if (fileOutputStream != null)
{
fileOutputStream.flush();
fileOutputStream.close();
}
}
catch (Exception e)
{
Log.e(TAG, "", e);
}
}
}

  测试结果如下:

下载文件:360MobileSafe_4.3.5beta.apk 链接:http://msoftdl.360.cn/mobilesafe/shouji360/360safesis/360MobileSafe_4.3.5beta.apk 大小:12.65MB

测试结果: DefaultHttpClient平均耗时:7275ms(第一次) 3861ms(第二次) HttpURLConnection平均耗时:5445ms(第一次) 3119ms(第二次)

HttpURLConnection传输效率更高

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下载文件:old offender.apk 链接:http://gdown.baidu.com/data/wisegame/79fb2f638cc11043/oldoffender.apk 大小:4.98MB

测试结果: DefaultHttpClient平均耗时:3780ms(第一次) 4008ms(第二次) 4209ms(第三次) HttpURLConnection平均耗时:3718ms(第一次) 4783ms(第二次) 3945ms(第三次)

二者相差无几

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下载文件:baidu首页html 链接:http://www.baidu.com 大小:使用DefaultHttpClient下载的是11.61KB的html(被baidu视为PC端浏览器访问),使用HttpURLConnection下载的是5.22KB的html(被baidu视为移动端浏览器访问)

测试结果:无效

说明:这也是某些测试说HttpUrlConnection下载速度快几倍所使用的链接,其实根本原因在于这两API下载的html大小就差了两倍,比较结果是不公平的

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下载文件:baidu首页logo 链接:http://www.baidu.com/img/bdlogo.gif 大小:1.54KB

测试结果:无效

说明:由于文件较小,有时候DefaultHttpClient比HttpURLConnection快很多,而下一秒的测试结果又反过来了,这是因为传输时间相差无几,而连接的耗时不确定,从而导致总耗时相差很大,所以无法判断谁的传输效率更高。

结论:文件越大,可能HttpUrlConnection的速度优势越明显,应该是SDK文档宣称的GZIP压缩传输导致传输时间缩短的原因,当然,前提是服务器得支持GZIP传输~

HttpClient与HttpUrlConnection下载速度比较的更多相关文章

  1. java分别通过httpclient和HttpURLConnection获取图片验证码内容

    前面的文章,介绍了如何通过selenium+Tesseract-OCR来识别图片验证码,如果用接口来访问的话,再用selenium就闲的笨重,下面就介绍一下分别通过httpclient和HttpURL ...

  2. HttpClient和HttpURLConnection的使用和区别(下)

    转自来自点击打开链接 接着上一篇,我们继续来分析HttpURLConnection的使用,以及两者的共同点和区别. 目录 用法 HttpURLConnection 区别 引用资料 用法 HttpURL ...

  3. Android 网络编程之---HttpClient 与 HttpURLConnection 共用cookie

    HttpClient 与 HttpURLConnection 共用 SessionId HttpClient 与 HttpUrlConnection 是Android 中HTTP操作最常见的訪问方式. ...

  4. 为HttpClient和HttpURLConnection添加中国移动代理

    转自: http://www.2cto.com/kf/201111/112100.html 在android中,一般需要联网的时候前,都要做一次网络的判断,判断当前的网络状态!然后开始请求网络 当我们 ...

  5. HttpClient和HttpURLConnection整合汇总对比

    性能 1.HttpUrlConnection直接支持GZIP压缩:HttpClient也支持,但要自己写代码处理. 2.HttpUrlConnection直接支持系统级连接池,即打开的连接不会直接关闭 ...

  6. android 中对apache httpclient及httpurlconnection的选择

    在官方blog中,android工程师谈到了如何去选择apache client和httpurlconnection的问题: 原文见http://android-developers.blogspot ...

  7. Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比

    比较的指标: 1.cpu 2.流量 3.电量 4.内存占用 5.联网时间 功能点: 1.重试机制 2.提供的扩展功能 3.易用性 4.是否https 5.是否支持reflect api,OkHttp有 ...

  8. HttpClient和HttpURLConnection的使用和区别

    https://www.cnblogs.com/liushuibufu/p/4140913.html 功能用法对比 从功能上对比,HttpURLConnection比HttpClient库要丰富很多, ...

  9. 关于HttpClient,HttpURLConnection,OkHttp的用法

    1 HttpClient入门实例 1.1发送get请求 /** * HttpClient发送get请求 * @param url 请求地址 * @return * @throws IOExceptio ...

随机推荐

  1. 关于使用AzureCli登陆提示SSLError的错误解决方案

    如果使用Powershell的azure cli命令登陆Azure时提示sslerror,大致如下的错误: 这个是由于你的网络前有网关造成的ssl验证没法通过. 解决方案: 在powershell中执 ...

  2. Leetcode题库——46.全排列

    @author: ZZQ @software: PyCharm @file: permute.py @time: 2018/11/15 19:42 要求:给定一个没有重复数字的序列,返回其所有可能的全 ...

  3. VS社区版 使用 OpenCover 获取测试代码覆盖率

    注:暂不支持VS2017 Visual Studio 2015 社区版没有集成代码覆盖率的功能,所以想在VS社区版中获取单元测试的代码覆盖率等数据,需要使用到插件 OpenCover. 下载 Open ...

  4. Delphi 之 菜单组件(TMainMenu)

    菜单组件TMainMenu 创建菜单双击TmenuMain,单击Caption就可以添加一个菜单项 菜单中添加分割线只需加“-”就可以添加一个分割线 级联菜单的设计 单击鼠标右键弹出菜单中选择Crea ...

  5. BZOJ2561 最小生成树(最小割)

    考虑kruskal的过程:按边权从小到大考虑,如果这条边的两端点当前不连通则将其加入最小生成树.由此可以发现,某条边可以在最小生成树上的充要条件是其两端点无法通过边权均小于它的边连接. 那么现在我们需 ...

  6. NOI前各种Idea总结以及各种文本乱堆

    转载请注明原文地址:https://www.cnblogs.com/LadyLex/p/9227267.html 不过这篇的确没什么*用了转转吧 2018-6-24 关于一类延迟标记(来自UR14 思 ...

  7. IDEA中新建Module时Module name、Content root、Module file location的含义

    如下图测试: 最开始默认情况下,Content root.Module file location两行,最末尾的数据跟Module name是相同的. 现在对三行数据,强制进行不同的命名,Finish ...

  8. 【题解】 bzoj1207: [HNOI2004]打鼹鼠 (动态规划)

    bzoj1207,懒得复制,戳我戳我 Solution: 挺傻逼的一个\(dp\),直接推就好了 这题在bzoj上的数据有点问题,题目保证每个时间点不会出现在同一位置两个地鼠,然而他有= =(还浪费我 ...

  9. 【BZOJ1487】[HNOI2009]无归岛(动态规划)

    [BZOJ1487][HNOI2009]无归岛(动态规划) 题面 BZOJ 洛谷 题解 哪来的这么多废话啊,直接说一个仙人掌得了. 然后就是要你求仙人掌最大独立集了.(随便蒯份原来的代码就过了) 不过 ...

  10. 关于程序设计中INF和MOD值的设定

    在取模操作中,我们常把MOD设置为1000000007 模一个大数和模一个质数可以减少冲突 而1e9+7又有一个很好的特点,就是相加不会爆int,相乘不会爆long long 在设置无穷大值时中我们常 ...