参考:http://blog.csdn.net/heng615975867/article/details/9012303

    尽管Android官网推荐在2.3及后续版本中使用HttpURLConnection作为网络开发首选类,但在连接管理和线程安全方面,HttpClient还是具有很大优势。就目前而言,HttpClient仍是一个值得考虑的选择。对于HttpClient的优化,可以从以下几个方面着手:

(1)采用单例模式(重用HttpClient实例)
    对于一个通信单元甚至是整个应用程序,Apache强烈推荐只使用一个HttpClient的实例。例如:

private static HttpClient httpClient = null;
 
    private static synchronized HttpClient getHttpClient() {
       if(httpClient == null) {
           final HttpParams httpParams = new BasicHttpParams();  
           httpClient = new DefaultHttpClient(httpParams); 
       }  
  
      return httpClient;
    }

(2)保持连接(重用连接)
    对于已经和服务端建立了连接的应用来说,再次调用HttpClient进行网络数据传输时,就不必重新建立新连接了,而可以重用已经建立的连接。这样无疑可以减少开销,提升速度。
    在这个方面,Apache已经做了“连接管理”,默认情况下,就会尽可能的重用已有连接,因此,不需要客户端程序员做任何配置。只是需要注意,Apache的连接管理并不会主动释放建立的连接,需要程序员在不用的时候手动关闭连接。

(3)多线程安全管理的配置
    如果应用程序采用了多线程进行网络访问,则应该使用Apache封装好的线程安全管理类ThreadSafeClientConnManager来进行管理,这样能够更有效且更安全的管理多线程和连接池中的连接。
    (在网上也看到有人用MultiThreadedHttpConnectionManager进行线程安全管理的,后查了下Apache的API,发现MultiThreadedHttpConnectionManager是API 2.0中的类,而ThreadSafeClientConnManager是API 4.0中的类,比前者更新,所以选择使用ThreadSafeClientConnManager。另外,还看到有PoolingClientConnectionManager这个类,是API 4.2中的类,比ThreadSafeClientConnManager更新,但Android SDK中找不到该类。所以目前还是选择了ThreadSafeClientConnManager进行管理)
    例如:

ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry); 
    httpClient = new DefaultHttpClient(manager, httpParams);

(4)大量传输数据时,使用“请求流/响应流”的方式
    当需要传输大量数据时,不应使用字符串(strings)或者字节数组(byte arrays),因为它们会将数据缓存至内存。当数据过多,尤其在多线程情况下,很容易造成内存溢出(out of memory,OOM)。
    而HttpClient能够有效处理“实体流(stream)”。这些“流”不会缓存至内存、而会直接进行数据传输。采用“请求流/响应流”的方式进行传输,可以减少内存占用,降低内存溢出的风险。
    例如:

// Get method: getResponseBodyAsStream()
    // not use getResponseBody(), or getResponseBodyAsString()
    GetMethod httpGet = new GetMethod(url);  
    InputStream inputStream = httpGet.getResponseBodyAsStream();

// Post method: getResponseBodyAsStream()
    PostMethod httpPost = new PostMethod(url);  
    InputStream inputStream = httpPost.getResponseBodyAsStream();

(5)持续握手(Expect-continue handshake)
    在认证系统或其他可能遭到服务器拒绝应答的情况下(如:登陆失败),如果发送整个请求体,则会大大降低效率。此时,可以先发送部分请求(如:只发送请求头)进行试探,如果服务器愿意接收,则继续发送请求体。此项优化主要进行以下配置:

// use expect-continue handshake
    HttpProtocolParams.setUseExpectContinue(httpParams, true);

(6)“旧连接”检查(Stale connection check)
    HttpClient为了提升性能,默认采用了“重用连接”机制,即在有传输数据需求时,会首先检查连接池中是否有可供重用的连接,如果有,则会重用连接。同时,为了确保该“被重用”的连接确实有效,会在重用之前对其进行有效性检查。这个检查大概会花费15-30毫秒。关闭该检查举措,会稍微提升传输速度,但也可能出现“旧连接”过久而被服务器端关闭、从而出现I/O异常。
    关闭旧连接检查的配置为:
    // disable stale check
    HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);

(7)超时设置
    进行超时设置,让连接在超过时间后自动失效,释放占用资源。
    // timeout: get connections from connection pool
    ConnManagerParams.setTimeout(httpParams, 1000);  
    // timeout: connect to the server
    HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
    // timeout: transfer data from server
    HttpConnectionParams.setSoTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);

(8)连接数限制
    配置每台主机最多连接数和连接池中的最多连接总数,对连接数量进行限制。其中,DEFAULT_HOST_CONNECTIONS和DEFAULT_MAX_CONNECTIONS是由客户端程序员根据需要而设置的。
    // set max connections per host
    ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(DEFAULT_HOST_CONNECTIONS)); 
    // set max total connections
    ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);

经过优化后,上一篇日志中的getHttpClient()方法代码如下:

[java] view plaincopy
  1. private static synchronized HttpClient getHttpClient() {
  2. if(httpClient == null) {
  3. final HttpParams httpParams = new BasicHttpParams();
  4. // timeout: get connections from connection pool
  5. ConnManagerParams.setTimeout(httpParams, 1000);
  6. // timeout: connect to the server
  7. HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
  8. // timeout: transfer data from server
  9. HttpConnectionParams.setSoTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
  10. // set max connections per host
  11. ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(DEFAULT_HOST_CONNECTIONS));
  12. // set max total connections
  13. ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);
  14. // use expect-continue handshake
  15. HttpProtocolParams.setUseExpectContinue(httpParams, true);
  16. // disable stale check
  17. HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
  18. HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
  19. HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
  20. HttpClientParams.setRedirecting(httpParams, false);
  21. // set user agent
  22. String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
  23. HttpProtocolParams.setUserAgent(httpParams, userAgent);
  24. // disable Nagle algorithm
  25. HttpConnectionParams.setTcpNoDelay(httpParams, true);
  26. HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);
  27. // scheme: http and https
  28. SchemeRegistry schemeRegistry = new SchemeRegistry();
  29. schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
  30. schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
  31. ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
  32. httpClient = new DefaultHttpClient(manager, httpParams);
  33. }
  34. return httpClient;
  35. }

附录:关于HttpURLConnection的优化,网上资料不多。从Android官网上看到一点,整理如下:

(1)上传数据至服务器时(即:向服务器发送请求),如果知道上传数据的大小,应该显式使用setFixedLengthStreamingMode(int)来设置上传数据的精确值;如果不知道上传数据的大小,则应使用setChunkedStreamingMode(int)——通常使用默认值“0”作为实际参数传入。如果两个函数都未设置,则系统会强制将“请求体”中的所有内容都缓存至内存中(在通过网络进行传输之前),这样会浪费“堆”内存(甚至可能耗尽),并加重隐患。

(2)如果通过流(stream)输入或输出少量数据,则需要使用带缓冲区的流(如BufferedInputStream);大量读取或输出数据时,可忽略缓冲流(不使用缓冲流会增加磁盘I/O,默认的流操作是直接进行磁盘I/O的);

(3)当需要传输(输入或输出)大量数据时,使用“流”来限制内存中的数据量——即:将数据直接放在“流”中,而不是存储在字节数组或字符串中(这些都存储在内存中)。

Android网络优化之HttpClient相关推荐

  1. Android网络优化攻略,简单了解一下?

    转自:掘金 - 究极逮虾户 https://juejin.cn/post/6896302142542315533 1  如何优化一个网络请求呢? 相信大家在面试的时候可能会被问到这个问题.今天我其实就 ...

  2. Android 网络优化方案

    转自:掘金-究极逮虾户 https://juejin.cn/post/6896302142542315533 面试官:小虾啊,我好想你啊,你都好久没来找我面试了呀. 小虾:emmmmmmm,这不是怕被 ...

  3. android使用HttpURLConnection/HttpClient实现带参数文件上传

    本文参考自[http://blog.csdn.net/crazy__chen/article/details/47703781] 在Android 2.3及以上版本,使用的是HttpURLConnec ...

  4. Android中利用HttpClient建立一次持久的连接

    首先,http协议是无状态的连接,之前的两种方式get,与post连接方式,每点击一次就启动了一个线程,而在启动线程时 很自然的就重新的new出了一个新的HttpClient,相当于两个客户端向服务器 ...

  5. android系统内置HttpClient库(WebView+ Http(s)URLConnection(ok-http)+ HttpClient(apache-http))

    android.webkit.WebView java.net.HttpURLConnection / javax.net.ssl.HttpsURLConnection org.apache.http ...

  6. Android中使用HttpClient实现HTTP通信效果

    HTTP通信,这一案例在操作的时候遇到N多种种问题,是前面看过几个实例里面最麻烦的一个,因为没有系统的接触过JAVA,所以出了很多错误,也无从下手解决,这里经过对错误的检索实现了HTTP通信,以做记录 ...

  7. android studio 引入httpclient,HttpClient不会导入Android Studio

    我有一个用Android Studio编写的简单类: package com.mysite.myapp; import org.apache.http.client.HttpClient; publi ...

  8. Android笔记 采用httpclient提交数据到服务器demo

    本例建立在上篇日志基础之上web端代码不变 布局文件增加了两个按钮 httpclient相对于普通get post提交方式优势在于不需手动指定传输的编码集 避免了乱码 </pre>< ...

  9. Android开发实现HttpClient工具类

    在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务.你可以把HttpClient想 ...

最新文章

  1. opencv数字图像处理(图像边缘)
  2. 一个公众号可以绑定几个小程序_如何实现微信小程序和公众号的绑定
  3. 训练softmax分类器实例_知识蒸馏:如何用一个神经网络训练另一个神经网络
  4. ASP.NET Core MVC 授权的扩展:自定义 Authorize 和 IApplicationModelProvide
  5. python压缩文件为zip-python 压缩文件为zip后删除原文件
  6. C++ primer第六章函数的学习
  7. 转:配置 SQL Server 2005 远程调试存储过程
  8. python 学习手册重点
  9. 【转】经典SQL语句大全
  10. 罗永浩回归!将开秋季旧机发布会:与iPhone 12同一天
  11. VeryCD 电驴(easyMule) 1.1.9 稳定版
  12. 植物科学常用数据库和生物信息学工具2020
  13. OP-TEE中的线程管理(一)
  14. oracle磁盘满了怎么办,ORACLE磁盘空间占满解决
  15. PLATO上线LAAS协议Elephant Swap,用户可借此获得溢价收益
  16. consider increasing the maximum size of the cache. After eviction approximately [10,239] KB of data
  17. 揭开AI产品PRD的面纱 | 浅谈其和互联网产品PRD的异同
  18. macd的python代码同花顺_手把手教你妙用MACD指标
  19. 计算机二级ppt学什么软件,计算机二级办公软件机考试参考资料.ppt
  20. 360加固android app反编译,apk360加固脱壳

热门文章

  1. confluence7安全补丁_centos7安装confluence遇到的问题
  2. mysql file-pos_mysql-5.7 调整mysql的复制方式由master_log_file+master_log_pos 到gtid 详解
  3. oracle 生成 json文件,oracle - PLSQL导入JSON并导出为JSON文件 - 堆栈内存溢出
  4. gateway java_基于SpringCloudGateway 实现的网关
  5. java程序设计B_Java程序设计11——GUI设计与事件处理B
  6. mysql 随机选择数据_从MySQL随机选取数据
  7. spring初始化web_了解Spring Web初始化
  8. tcp前4字节消息长度_RocketMQ的消息存储格式
  9. python调用c#dll_详解Python 调用C# dll库最简方法
  10. 一文教你如何高效使用 IDEA !