到今年6月,我国的手机网民已经达到了3.88亿,超过了电脑终端。相信有智能机的同学都用过手机上网冲浪。但是手机的电量很快被用光了恐怕是每个人都不能忍受的一件事情。而打开数据连接进行网络数据的传输是很耗费电量的,如果用户发现你的应用榨干了他电池里的电,恐怕他会第一时间将你的应用给卸载掉。所以进行网络应用的开发理解怎样才能更省电就很有必要了。

         
        如果数据连接一直保持着激活的状态,那么它的耗电量是很惊人的,所以手机会在网络空闲的情况下自动休眠数据连接来达到省电的目的。以3G网络来举例,它有三个不同的状态:
 
        Full power: 全力工作,网络信号和电量的消耗都很高。
        Low power:耗电量是Full power的一半,当然信号也差一些。
        Standby: 耗电量很少,相当于休眠了。
   
        手机会根据当前网络的使用情况来进行状态的切换,如下图所示,这就是无线网络的状态机。当处于Full Power状态空闲5秒后就会进入到Low Power状态,如果还空闲12秒则进入到Standby状态。而从Standby状态重新切换到Full Power状态则需要2秒的延迟,从Low Power状态则需要1.5秒。理解这个状态机就可以很好地理解怎么在传输网络数据的时候更省电。
 
          
        比如说我们现在有3秒的数据要进行传输。一种策略是每隔18秒传输1秒,第二种则是将这3秒的数据一下子传完。让我们来分析一下这两种策略是如果影响状态机以及它们的耗电情况是怎么样的。
      
        第一种: 传输1秒加上等待的5秒,处于Full Power状态为6秒。传输3次,总共为18秒。另外每次处于Low power状态等待的12秒加上1.5秒的延迟,传输3次就为(12+1.5)×3=40.5秒。
        第二种:传输3秒加上等待的5秒,处于Full Power状态为8秒,然后在Low Power状态等待12秒后进入到StandBy状态。
 
        经过分析,将耗电情况画成饼图就如下图所示。我们可以很清楚地看到采用第二种策略要比第一种策略省电得多。这其实就是打包传输数据的思想,也就是说将很多零散紧凑地数据传输打成一个包来一次性地传输可以节省很多的电量。
  
 
        另外我们还要尽可能地减少网络连接的数量。因为每新建一个网络连接都要比你利用当前已经存在的网络连接所耗费的资源和电量多。所以如果现在有可以重复利用的网络连接,我们要优先利用这些连接而不要去新建连接。和前面所说的打包思想类似地就是如果有很多连接请求,我们也可以将这些请求打成包放在一个请求中,这样我们就需要一个网络连接就可以了。
 
       还有一种减少网络连接数量的方法就是当连接不用的时候不要等到它超时,而要自己主动关闭。但这可能跟前面所说的网络连接复用有冲突之处。解决的办法就是用完后不是马上关闭连接,等待一段时间(当然要在超时前)如果还没有用到的话再关闭这个连接。
 
       Prefetch Data也是一种省电的有效的策略。以一个看新闻的应用为例,如果有10条新闻,当用户看第一条的时候我们就可以一下子把这10条新闻都取过来,也是一种类似打包的策略。这种策略有如下的优点:
       
        降低了激活网络的次数,也就减少了状态机切换时等待所浪费的电量。
        提高了用户体验,用户在打开下面的新闻的时候就不需要再等待数据传输的过程了,可以立即打开,响应速度可以很快。
 
        但是过犹不及,如果这种策略使用得太过了的话也会带来风险,反而可能会加大了程序的耗电量,还会消耗掉用户的流量。至于到底要用到什么程度要看实际的情况,一般来讲可以采用"四舍五入”的方式即用户如果有50%的可能性会用到这些数据就可以将其Prefetch。相信大家都有在网上看过在线视频,当你看到10分钟的时候,视频可能已经下到20分钟了,然后就不再下载了,直到你看到如18分钟的时候,视频再下载10分钟的内容到缓存。这其实也可以看作是一种Prefetch Data的应用。
   
      在android 4.0.4的sdk DDMS中,有了一个工具:Network Traffic Tool 。通过这个工具可以实时地监测网络的使用情况,使程序员更好的发现自己的应用程序在什么时候发送接收了多少的网络数据,从而来改进自己的应用程序来达到省电的目的。
 
       如果要更加清楚地看清每一个网络连接的使用情况可以在程序中对网络连接打tag,如对socket连接可以这样:

点击(此处)折叠或打开

  TrafficStats.setThreadStatsTag(0xF00D);

  TrafficStats.tagSocket(outputSocket);

  // Transfer data using socket

  TrafficStats.untagSocket(outputSocket);

       对于Apache HttpClient and URLConnection 会自动打上tag,所以只要设置上tag名就可以了:

点击(此处)折叠或打开

  TrafficStats.setThreadStatsTag(0xF00D);

  try {

     // Make network request using HttpClient.execute()

  } finally {

     TrafficStats.clearThreadStatsTag();

  }

       下图即我在为一个httpClient打上tag后得到的网络使用情况,系统用红色做出标示区分开来:
   
 

另外一个可能会很耗电的方面就是应用程序的更新。应用的更新主要是有两种,分别是:

 
       Polling:周期性地连接服务器来请求数据。这样对于使用3G网络的手机来说,程序每请求一次就会将手机网络的状态机置于高耗电状态20秒左右的时间,累积起来所浪费的电量也是很客观的。不推荐使用这种方式。
  
       Google Cloud Messaging: 是google的一种轻量级的实现,可以让服务器将更新的内容push到目标手机上。相比于Polling,可以省更多的电,所以推荐使用这种方式。
 
       手机在下载数据时候会将状态机一直处于Full Power状态,长时间地下载会很快把电池中的电用光。所以从这个方面考虑省电的话就要减少下载量。这个和前面所讲到的Prefetch Data并不矛盾,我们所要减少的就是减少不必要的下载。如下载一个很大的图片的时候,可以在服务器端将图片做一下处理,减少图片的大小,然后我们再下载。另外就是可以缓存会经常用到的数据到本地,减少这种重复的下载而且还可以提高用户的体验。

 
        最后非常重要的一点就是要根据实时的网络连接情况来更改连接网络的方式。比如说现在wifi打开了,那我们的应用程序就不应该再继续使用3G网络了,而要切换到wifi来。因为wifi可以在较小的耗电量下以一个较高的带宽下载大量的数据。除去wifi,对于数据连接来讲,速度越快,耗电量就越高,有如下规律:LET>3G>2G。所以在同样的时间里,高速网络等待状态机转换的过程中耗的电就更多了。所以在较好的网络情况下可以考虑更“过”的使用Prefetch Data策略。
 
 
        更多详细的内容请查看google的官方文档:http://developer.android.com/training/efficient-downloads/index.html 

[Android Traffic] 让android应用在传输网络数据的时候更省电的更多相关文章

  1. Android训练课程(Android Training) - 使用Volley传输网络数据(Transmitting Network Data Using Volley)

    使用Volley传输网络数据(Transmitting Network Data Using Volley) Volley 是一个 HTTP 库,它使得在Android应用程序中操作网络更容易,是重要 ...

  2. Android利用tcpdump和wireshark抓取网络数据包

    Android利用tcpdump和wireshark抓取网络数据包 主要介绍如何利用tcpdump抓取andorid手机上网络数据请求,利用Wireshark可以清晰的查看到网络请求的各个过程包括三次 ...

  3. Android之MVP模式实现登录和网络数据加载

    MVP简介 相信大家对 MVC 都是比较熟悉了:M-Model-模型.V-View-视图.C-Controller-控制器,MVP作为MVC的演化版本,也是作为用户界面(用户层)的实现模式,那么类似的 ...

  4. Android应用中使用AsyncHttpClient来异步网络数据(转载)

    摘要: 首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测 ...

  5. Android应用中使用AsyncHttpClient来异步网络数据

    首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测试的Ac ...

  6. 【转】Android应用中使用AsyncHttpClient来异步网络数据

    摘要: 首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测 ...

  7. Android架构:用消息机制获取网络数据

    网络请求,不管是什么协议,是长连接还是短连接,总是一个异步的请求,过程包括:加请求参数->发起请求->接收响应->解析数据->获得业务数据. 最挫的做法是,业务代码包揽所有这些 ...

  8. Android利用Fiddler进行网络数据抓包

    最新最准确内容建议直接访问原文:Android利用Fiddler进行网络数据抓包 主要介绍Android及IPhone手机上如何进行网络数据抓包,比如我们想抓某个应用(微博.微信.墨迹天气)的网络通信 ...

  9. [Android Traffic] 看无线电波如何影响网络操作]

    转载自: http://blog.csdn.net/kesenhoo/article/details/7391031 Optimizing Downloads for Efficient Networ ...

随机推荐

  1. NIO--1

    1.为什么不直接用jdk NIO(1) API繁杂(2) 原始NIO可靠性不是很高.可靠性包括:断开重连,网络闪断,半包读写,失败缓存(3) NIO 的epoll BUG会导致多路复用器Selecto ...

  2. easyui中的依赖关系

    参考自:http://www.easyui.info/archives/765.html 在使用easyui的过程中发现各个组件直接存在依赖关系,也就是上层的复杂组件依赖于一个或者多个简单组件,复杂组 ...

  3. Codeforces Round #387 (Div. 2) 747F(数位DP)

    题目大意 给出整数k和t,需要产生一个满足以下要求的第k个十六进制数 即十六进制数每一位上的数出现的次数不超过t 首先我们先这样考虑,如果给你了0~f每个数字可以使用的次数num[i],如何求长度为L ...

  4. Codeforces 672D Robin Hood(二分好题)

    D. Robin Hood time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  5. vue-计算属性-computed

    /* 计算属性:vue中对数据进行一些组合与计算的话,可以使用computed(计算属性); //例如:获取当前日期,组合 */ // 组合变成10-1 var vm = new Vue({ el: ...

  6. Tomcat学习笔记(八)

    Tomcat载入器(二) Tomcat拥有不同的自定义类加载器,以实现对各种资源库的控制. 1.同一个web服务器里,各个web项目之间各自使用的java类库要互相隔离.  2.同一个web服务器里, ...

  7. Python之Excel编程

    excel编程:excel中是unicode编码方式 需要使用xrld,xlwt和openpyxl这三个模块,需先通过pip install下载     xlrd 读取模块:xls,xlsx     ...

  8. 从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式

    如何正确使用NIO来构架网络服务器一直是最近思考的一个问题,于是乎分析了一下Jetty.Tomcat和Mina有关NIO的源码,发现大伙都基于类似的方式,我感觉这应该算是NIO构架网络服务器的经典模式 ...

  9. log4net日志分割,按大小分割

    最近写了一个socket通信的手表在线服务端,在日志方面,记录下Log4net日志分割 1.引入log4net.dll 2.web.config添加configsection handler 映射: ...

  10. [bzoj3122][SDOI2013]随机数生成器 ——BSGS,数列

    题目大意 给定递推序列: F[i] = a*F[i-1] + b (mod c) 求一个最小的i使得F[i] == t 题解 我们首先要化简这个数列,作为一个学渣,我查阅了一些资料: http://d ...