不耗电传输数据(一):高效网络连接下载优化

6 篇文章 0 订阅
5 篇文章 0 订阅

Contents

高效网络连接下载优化... 1

无线状态机... 1

应用如何影响无线状态机... 2

预取数据... 2

批量传输和连接... 3

降低连接数量... 4

用网络分析器定位问题... 4

 

高效网络连接下载优化

用无线网络传输数据是耗电量最大的操作之一。为了降低网络活动的耗电量,理解连接模型对下层无线硬件的影响很重要。

这一课会介绍无线网络状态机并解释了你的应用是如何与之交互的。提供了一些方法,减少数据连接,用预取,绑定传输,来降低数据传出的耗电量。

线状态机

全面启动的无线网络耗电量巨大,当不用的时候为了省点它进入不同能量状态,同时又要降低启动所花费的时间。

典型的3G网络信号状态机有三个能量状态:

全能量:当有一个活动的连结时,允许设备以最高速率传输数据。

低能量:中间状态,大约消耗全能量电量的50%。

待机:最低电量消耗状态,在这个状态没有活动的连接或没有请求。

尽管地能量和待机省很多电,但也引入了重大网络延时。从地能量状态到全能量状态约需要1.5秒,从待机状态进入全能量需要2秒多。

为了减少延迟,状态机从全能量态进入低能量态引入一个延迟。下图用AT&T演示了一个3G网络

每台设备的信号状态机的延迟时间和恢复时间跟当前运行的网络技术有关(2G,3G,LTE,etc.),并通过设备正在使用的运营商定义和配置。

这节课基于AT&T的数据描述了一个由代表性的典型3G网络的状态机。但是,这一基本原则和结果适用于所有无线网络。

对于典型的浏览网页,这项策略非常重要。他防止用户浏览网页时那些不受欢迎的延迟。相对来说一个比较小的休眠时间也保证了当一个会话结束时,无线网络能进入一个低耗电的状态。

不幸的是,这个策略影响了运行在Android系统上的应用效率,在Android系统中,应用即运行在前台(延迟会影响效率),也在后台运行(应该优化电池使用)。

用如何影响无线状态机

每次进创建一个新的连接,状态机就进入全能量态。在上面的典型的3G网络状态机例子中,数据传输时,会持续保持在全能量态,外加5秒钟休眠时间,然后是12秒钟低能量态时间。所以典型的3G设备,一个会话大约持续20秒要耗电。

在实际使用中,如果一个应用不绑定传输数据,并每18秒传送1秒数据,就会导致无线网络一直运行,也就是刚要进入待机模式时,又恢复全能量模式了。也就是1分钟里,大约18秒钟时全能量态,42秒钟是低能量态。

比较而言,如果应用每分钟绑定传输3秒数据,那么全能量态只会持续8秒,低能量态12秒。

后一个例子是的网络在每分钟有40秒待机时间,大大降低耗电量。

取数据

数据预取对于降低独立数据传输会话数量效果显著。数据预取允许你在一个单独的连结中满负荷的一次性下载你可能在一段时间内所需要的所有数据。

预取同时改进了用户体验,降低了操作和浏览数据之前等待下载完成这部分延迟。

但是,如果用的太频繁,预取可能会有增加耗电量和带宽使用的危险,同时也消耗流量,因为有可能预取了很多无用数据。确保预取不影响应用启动也很重要,因为有可能应用要等预取结束才能启动。在实际实现中,可能意味着逐步处理数据,或者建立一个基于优先级的连续传输,应用启动所需的数据先传出,先处理。

如何预取决定于数据大小和后续被用到的可能性。一个粗略的指导,基于上面的状态机,对于当前用户会话,假如数据被用到的几率是50%,同时考虑到下载到无用数据的消耗和预取省下的电量,你可以下载约6秒钟(1到2Mb)数据。

一般来说,预取一次,大约1到5兆字节,就只需要每2到5分钟再次启动下载,就比较好。

按照这个原则,像视频文件这样的大量下载,就应该定期的(每2到5分钟)大块下载,高效的预取下面几秒很有可能被浏览到的数据。

注意进一步下载应该被绑定,像下面一段所说的,批量传输和连接,而且这些近似值应该根据传输类型和速度的不同而调整。

看一个例子:

音乐播放器

你可以选择预取整个专辑,但是用户可以听完一首就不听了,这样你浪费了大量的下载和电量。

更好的选择是留一个缓冲区,缓冲正在播放和将要播放的两首曲子。对于流音乐,不要一直维护一个持续的流,这会导致连接网络状态机一直处在高能耗状态,考虑用HTTP直播流,批量传输数据,模拟上面的预取的操作。

新闻阅读器

很多新闻类的应用为了降低带宽消耗,在用户选择一个新闻类型后,只下载标题,当用户点进去再去下载具体文章,如果用户只是滑动到某个新闻,只下载缩略文。

用这种策略,用户浏览标题,切换新闻类型,察看文章时,网络就要一直保持激活状态。不仅如此,当用户切换新闻类型和察看具体文章时,状态机的切换会带来大量延迟。

更好的策略是在启动时预取一定数量的数据,首先是第一组新闻标题和缩略文,确保降低应用启动延时,然后继续下载剩下的新闻标题和缩略文和主要标题列表内的文章的文字。

另一个策略就是预取每个标题,缩略文和文章文字甚至图片,一般在后台周期性调度。但是这种策略有可能导致消耗大量带宽和电量,下载了很多不需要的东西,所以要慎重使用。

另一个方案就是当连接WiFi时全下载,有可能还需要连接着外接电源。

批量传输和连接

每次你初始化一个连接,不管传输多少数据,都意味着引起无限网络20秒钟的耗电,假设是一个典型的3G网络。

如果你的应用每20秒ping一下网络,只是为了确认应用还在运行并且对用户可见,会导致无线网络一直耗电,进而导致大量耗电,尽管没传输数据。

基于此,创建一个待传输队列绑定数据传输很重要,如此,你可以把邻近的网络请求同时执行,让无线网络尽量降低耗电时间。

背后的逻辑就是在一个会话中尽量多传输数据,而不要总是启动会话。

这意味着你要把能够容忍等待的数据请求先放队列,用预调度更新和预取对时间敏感的传输先执行。相似的,你的调度更新和定期预取也负责那些待传输队列的调度。

还是用预取的例子。

假设新闻应用使用上文预取的方法。新闻阅读器收集分析数据,了解用户的阅读模式,归类最受欢迎的文章。为了刷新新闻,每小时更新。为了省带宽,不下载所有文章的图片,只预取缩略文,和最受欢迎的文章的图片。

在这个例子中,应用收集的所有分析信息都应该绑定并入队列下载,而不是以收集完就下载。该结果绑定传送应该在一个图片下载完或者每小时更新完成后。

任何时间敏感或用户请求的传输,比如图片下载,都应该优先定期调度。计划的更新应该在用户请求数据的同时执行,并把下次更新的时间设成当前时间加上间隔。这个策略把常规的更新和一个时间敏感的又必须执行的图片下载绑定起来。

降低连接数量

一般来说,重用已有会话比创建新会话省电。重用连接也能帮助网络更智能的处理拥堵等其他网络数据传输问题。

不要同时创建多个会话下载数据,也不要用一系列的GET取数据,而应该尽量在一个GET里获得所有数据。

例如,对每个新闻文章只用一个连接和响应就比多个新闻类型用多次请求效率高。无线网络需要一直保持激活来传输与客户端和服务器超时相关的结束/结束通知包,所以当连接不再需要时,把它关掉而不是等待超时。

即便如此,关掉一个连接它就不能复用了,增加了建立一个新连接的费用。一个比较有用的折中办法就是不要立即关掉连接,但是在超时之前关闭它。

用网络分析器定位问题

用网络分析器跟踪你的应用的网络访问。你可以检测到应用什么时候,如何传输了数据,用来优化代码。

下图显示了应用每隔大约15秒钟就取数据,也就是说通过预取和绑定的优化,能大大提高效率。

通过检测数据传输频率,每次传输的数据量,你可以知道那些地方可以改进。一般来说,一要找的是那些小细尖,看能否延迟请求;或者让后续传输提前。总之就是绑定传送。

为了更好的识别传输的小细尖,Traffic Stats API允许你用TrafficStats.setThreadStatsTag()给一个线程中的传输添加标签,然后用TrafficStats.tagSocket()和TrafficStats.untagSocket()对线程中Socket添加和删除标签。例如:

TrafficStats.setThreadStatsTag(0xF00D)
TrafficStats.tagSocket(outputSocket)
// Transfer data using socket
TrafficStats.untagSocket(outputSocket)

HttpURLConnection库基于TrafficStats.getThreadStatTag()自动给Socket打标签。这个库也通过keep-alive池自动给Socket打和去除标签。

private class IdentifyTransferSpikeTask extends AsyncTask<String, Void, String> {

    @Override

    protected void onPreExecute() {

      TrafficStats.setThreadStatsTag(0xF00D);

    }



    @Override

    protected String doInBackground(String... urls) {

        try {

            // Make network request using HttpURLConnection.connect()

        }

    }



    @Override

    protected void onPostExecute(String result) {

        TrafficStats.clearThreadStatsTag();

   }

}

Socket标签在Android4.0中就支持了,但是时事统计仅在Android4.0.3及以上版本支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值