到今年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. LeetCode -- Longest Increasing Subsequence(LIS)

    Question: Given an unsorted array of integers, find the length of longest increasing subsequence. Fo ...

  2. linux下对/sys/class/gpio中的gpio的控制 (转)

        在嵌入式设备中对GPIO的操作是最基本的操作.一般的做法是写一个单独驱动程序,网上大多数的例子都是这样的.其实linux下面有一个通用的GPIO操作接口,那就是我要介绍的 “/sys/clas ...

  3. query的list()和iterate()区别 面试题

    query的list()和iterate()区别 1.返回的类型不一样,list返回List,iterate返回iterator 2.查询策略不同. 获取数据的方式不一样,list会直接查询数据库,i ...

  4. poj 2187 Beauty Contest(二维凸包旋转卡壳)

    D - Beauty Contest Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  5. python 使用urllib2下载文件

    #! usr/bin/python #coding=utf-8 import urllib2 fp = open('test', 'wb') req = urllib2.urlopen('http:/ ...

  6. Linux内核中的中断栈与内核栈的补充说明【转】

    转自:http://blog.chinaunix.net/uid-12461657-id-3487463.html 原文地址:Linux内核中的中断栈与内核栈的补充说明 作者:MagicBoy2010 ...

  7. 终于遇到了传说的ie 6 img 3px的bug

    最近在做一个网站,基本上已经算完成,就开始完善细节部分了. IE6可能是微软最为YD 的一款浏览器了吧,至今还没有退出历史的舞台,尽管google都宣布不在支持它了. 因为该死的ie6,虽死但是牢牢地 ...

  8. ECMAScript和JavaScript的关系

    JavaScript 是一种基于 ECMAScript 规范的脚本语言,并在此基础上进行了自己的封装.ECMAScript 不是一种编程语言,仅仅是一种脚本语言规范,由欧洲计算机协会制定和发布,任何基 ...

  9. 【转载】性能监视器(SSAS)

    使用性能监视器,您可以通过性能计数器监视 Microsoft SQL Server Analysis Services (SSAS) 实例的性能. 性能监视器是用于跟踪资源使用情况的 Microsof ...

  10. IE常见兼容问题

    图片有边框 CSS 增加 border:0; border,在IE 模式下不算在宽度内;