如果你正在以“服务器”方式思维编写手机应用,那么你做错了 已翻译 100%

威廉打个 投递于 2013/09/22 15:10 (共 15 段, 翻译完成于 10-10)
阅读 13174
收藏 302
26
加载中

电量对于手机来说就像沙漠中的水一样。它代表了生命。如果你把数据中心服务器上的朴素的编程技巧应用到手机上,你的手机会被“渴”死。

这一点已经被Reto Meier活灵活现的展示了,他是Android开发者关系维护团队的技术带头人,下面是其一系列非凡的教学视频:

之所以说它们是非凡的,是因为它们简短,且切中要害,充满了有用的想法和技巧。尽管Android有着独特的目标,上面目录中所列的教程仍具有通用意义。

lwei
lwei
翻译于 2013/09/24 15:44
5

下面举例说明服务器编程和手机编程的区别,在服务器环境中,从一个服务器上拷贝一个文件到另一个服务器上通常需要一到两个管道。从一个文件描述符中读取一块数据,然后把它写入到另一个文件描述符中。这是一个同步的过程。你可能会在数据块大小和其它一些技巧上费点儿脑细胞,但那都是基本的。在手机上使用这种朴素而自然的“吸水”式逻辑却是错误的,它是一个Little Cookie 的过程,我们后面会讲到。问题就在于它吸干了手机电池。为什么? 因为手机无线信号装置将被迫持续工作。这又是为什么? 等会儿你会了解到更多,但是你需要做的是通过分批和正确的规划信息传输来最小化无线信号的使用。注意,你已经不在堪萨斯州境内了哦。 

这将把我们引向...

lwei
lwei
翻译于 2013/09/24 16:25
4

核心想法: 手机中的无线通信最耗费手机电池的电量。每次你发送数据时,无论数据有多小,无线通信都会被启动20-30秒。所以你每一个决定都应当基于最小化无线通信启动次数这一初衷。通过改变你的app处理数据传输的方式,可以极大地提高电池使用时间。当用户需要获取他们的数据时,窍门就是在用户体验和数据传输之间做出平衡,同时使得电量损耗最小。app要想获得这种平衡,可以把重复和间断的数据传输捆绑在一起,然后一次性的主动的预先获取那些间断的传输数据。

lwei
lwei
翻译于 2013/09/24 16:49
3

手机无线通信如何工作?

为了最小化无线通信来减少电量的损耗,首先你的了解手机无线通信是如何工作的。视频已经清楚的解析了手机通信的全部过程,如下为其中的一些要点:

  • 手机无线通信是被一个试图平衡低延迟和更长的电池寿命的状态机控制的。手机无线通信不会永远保持一个状态,它将进入不同的状态作为延长电池寿命的一种手段,但是如果要通过无线电发送数据则必须要切换到全功率状态。
  • 首先无线通信处于待机模式,该模式下电量消耗最低,直到一个应用启动了数据传输。
  • 要发送数据无线通信需要切换到全功率模式,这个过程到发送数据前需要大约2秒的时间。无线通信将在全功率模式下保持一段时间以防止更多数据需要被传输。这样它就避免了加速到全功率状态的时间开销。状态切换本身就是一个显著的电量消耗,因此需要最小化。
  • 如果在接下来5-10秒时间内没有任何数据传输,通信状态将会切换到一个中间额低功耗状态,这个状态它将使用更少的电量并且转换到全功率状态所需时间也更短。
  • 如果在接下来的30~60秒内任然没有任何数据传输,通信状态将会回退到待机状态。
  • 确切的延迟和尾时间因运营商、网络和设备而异。
bigtiger02
bigtiger02
翻译于 2013/09/25 10:31
5

很明显传输数据有两种模型(如果你天真的只知道在手机上发送数据,那你没救了):

  • Big Cookie Model: 尽可能的对下载进行调度,最大限度的减少传输次数,最大化利用带宽。
  • Little Cookie Model: 传输数据尽可能的小并频繁的进行数据交互。

那种方式更好?Big Cookie. Little Cookie 频繁大量的使用无线通信。每次数据传输后,无线通信保持5秒的全功率状态,随后在回到待机状态前,将保持10~60秒的低功率状态。所以频繁发送小量数据会大量消耗电量。比如每15秒发送一次分析数据和用户断续的点击链接,其结果将可能导致持续保持无线通信状态。所以不要那样做。

bigtiger02
bigtiger02
翻译于 2013/09/25 14:00
5

你的app应该做些什么?

了解手机状态机的好处就是如果你了解它,那么你可以在应用延迟策略和电量使用之间做出权衡。这个视频讲述了大量有关权衡的技术:

  • 最小化无线状态转换次数
  • 根据你应用电量使用情况做出判断
    • 通过如下方式生成图表:Logcat logging/应用资源优化/DDMS中的网络使用统计
  • 分析电池使用效率图表:
    • 寻找电量转移规律。这将导致无线通信的使用和电量消耗。更新周期越短,电量损耗越大。
    • 从图表中的找出短小或持续时间短的请求片段,这些请求片段可以被一起发送或预取。
  • 为接下来2-5分钟预取数据(1-5mb)
    • 这样做将会降低延迟并提高电池性能。通过下载所有数据用户很可能只需要一次请求而不是单一满负载连接,这样明显减小了无线通信使用次数。
    • 最大的挑战就是要搞清楚什么需要下载和什么时候不需要在用不到的数据下载上浪费电量。
    • 3G网络下,你可以在6秒内预取到足够的2-5分钟内应用需要用到的用户的会话数据,数据大小大约为1-5mb。如果数据在当前会话中有50%的机率不会使用到,那么数据不匹配的成本将会使节省的潜在价值大打折扣。
    • 并不是所有网络都是以相同的速率传输数据,所以需要在预取数据和网络效率上做出平衡。根据每个网络的传输速度和开销情况必须必须增加或减小预取缓存的大小。在速度更快的4G网络上,显然预取更多用户的数据电量消耗也更大。
    • 当手机无线处于激活状态时数据传输更有效。所以如果一个时间敏感传输被初始化了,通过立即传输数据来抢占利用这一状态(译注),任何数据传输需要在几分钟之内被执行。
    • 例如,如果用户需要阅读一片文章,这是一个预取用户接下来几分钟内需要阅读的其他内容的好时机。
    • 对于一个音乐播放器,只需要在缓冲区保持一首或以上的正在播放的歌曲,而不需要下载一整张专辑,因为很有可能用户根本不会听。
    • 对于新闻阅读器,最幼稚的方式是只下载顶层新闻和缩略图,这将使得无线通信一直处于忙碌状态。相反,你应该下载第一组新闻的头条、缩略图和文章内容,并稍候获取另一个批次的新闻。你可以尝试无论深度优先或广度优先策略,更好的办法是相信科学。保持追踪你用户和他们朋友所阅读的东西来预测他们可能阅读的新闻,你应该预取这些数据。或者你可以预取所有的东西,如果数据从来都不会用到的话那这开销太贵了。
    • 当电池寿命和带宽不是非常重要的时候(比如充电时),根据使用设备状态来调度下载。
    • 根据用户当前的活动来修改预取的策略。当应用被打开时和用户任然停留在某个界面时,应该预取更多的数据。
    • 一般来说,当应用程序处于后台时,不要预取数据。
    • 不要延迟应用启动,不要使用初始界面。在后台并发的预取数据来最大程度减少应用启动等待时间。
    • 如有可能,使用HTTP实时流,它将一次性传输数据,不同于连续流(它将使得无线通信一直保持激活状态)。
    • 批量捆绑进行所有非实时敏感的数据传输。
    • 在下个实时敏感操作发生时一次性批量传输数据。
    • 如果必须传送重复事件,随机它的周期性。
    • 如果一个操作对时间不敏感,比如上传图片,等待30秒可能会更好,万一另一个图片或数据也需要上传的话,可以一起批量处理。(详见SyncAdapter)
  • 消除客户端轮询
    • 使用Google Cloud Messaging。当有数据需要发送时候数据只会发送到你的手机设备上,因此没有轮询循环。它(Google Cloud Messaging)可以提供更低的延迟和更好的电量使用。
  • 降低数据传输的大小和频率
  • 使用刷新按钮
  • 根据应用使用降低更新频率
  • 创建一个批处理队列,你可以向队列添加容忍延迟的数据传输。下次你执行一个需求传输时,你也可以传输队列中的所有数据。如果应用在数据传输前关闭,可能发生数据丢失。解决办法是将数据保存到本地数据库,并从数据库查询需要传输的数据,应用关闭后数据库中的数据并不会丢失。Android中有一个叫做SyncAdapter 的东西可以用来来简化这上述过程。它是一个最佳实践。
bigtiger02
bigtiger02
翻译于 2013/10/10 10:23
9

这些视频对所有这些都做了更为详细的介绍,尤其是SyncAdapter,所以值得好好看看。

这些视频把之前尚未讲清楚的事情都说清楚了: 在基于无线通信的手机设备上进行编程是一个特殊的领域,要想把它做好需要特定的知识和技巧。如果你一直想知道为什么app那么耗电,而电池总是没有想象的那么耐用,现在都可以轻松了解了。

lwei
lwei
翻译于 2013/09/24 17:11
2

来自评论的内容

iOS7 说明

Plorkyeran: iOS最终在 iOS 7 中添加了后台数据获取,但却被严格限制了(操作系统决定应用什么时候去获取,而不是应用本身决定,实际使用中它可能会和一天一次一样少)。除此之外,仅有有限的几种类别的应用可以后台工作(诸如音乐播放器,voip应用,和位置跟踪器),事实上,他们拒绝那些声称有豁免权而实际上没有的应用。

dzamir: 事实上 iOS 7 使用本文描述的相同策略:它同时唤醒需要后台下载的所有应用以最小化无线功能的打开时间。

开源中国首席投资人
开源中国首席投资人
翻译于 2013/10/01 22:06
2

担心电量使用情况是不是为时尚早?

miratrix: DCH(全功率状态)和PCH(最低功率、寻呼等待状态)之间(的电量使用,译注)相差了几个数量级。上次我测试的时候,在~3.7V电压下,无线通信在两种状态下的电量使用分别是:~100mA 和 ~1mA。所以,这并不是几分钟电池寿命的事情,而是相当于很多个小时的待机状态啊。用户通常都不喜欢刚充满电的手机一下就没电了。

我曾经看到过一些应用做过的疯狂的事情,这些事情对于电量有着显著的消耗。一个很流行的Android天气时钟小部件每分钟更新部件上的分钟数字,每15分钟(使用了GPS和无线通信)更新天气信息,这种行为轻而易举的使得手机原本可以待机几天的电池寿命缩短到不足8个小时。

bigtiger02
bigtiger02
翻译于 2013/10/10 13:19
5

我不认为每个应用都要基于最小化唤醒全功率状态原则来做出决定, 但是在另一方面,所有的开发者至少应该试图尽可能多的了解他们所工作的平台,这样他们就会知道怎样在增加的每个功能上做出权衡。

kintamanimatt: 尊重已知限制和工作的最佳方式是绝不要过早的进行优化。如果你知道使用手机无线通信是一个非常昂贵的电量消耗,那么忽略这一原则是一件非常愚蠢的事情。这不是过早优化的问题,如果你一开始就知道问题出在哪里。这一性能问题是如此普遍以至于android团队将他们放在视频里面进行了介绍。

bigtiger02
bigtiger02
翻译于 2013/10/10 13:31
4
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(33)

bigtiger02
bigtiger02

引用来自“scucoder”的评论

翻译问题:
《担心电量使用情况是不是为时尚早?》第二条评论第一句。
原文:kintamanimatt: Respecting known limitations and working within best practices is absolutely not premature optimization.
译文:kintamanimatt: 尊重已知限制和工作的最佳方式是绝不要过早的进行优化。
结合后文,我认为正确的译文:kintamanimatt: 尊重已知限制和工作的最佳方式绝对不属于“过早优化”。
翻译应该刚好翻译反了意思。

感谢提醒,确实如此。
Xsank
Xsank
涨姿势了
s
scucoder
翻译问题:
《担心电量使用情况是不是为时尚早?》第二条评论第一句。
原文:kintamanimatt: Respecting known limitations and working within best practices is absolutely not premature optimization.
译文:kintamanimatt: 尊重已知限制和工作的最佳方式是绝不要过早的进行优化。
结合后文,我认为正确的译文:kintamanimatt: 尊重已知限制和工作的最佳方式绝对不属于“过早优化”。
翻译应该刚好翻译反了意思。
人头马没面
人头马没面
啥意思 那QQ等长连接有问题?
10书生
10书生
请教一个问题,如果从移动端建立一个TCP连接到服务端,但不发送任何数据,此时移动端处于什么状态呢?
凉拌茶叶
凉拌茶叶

引用来自“hawkyoung”的评论

手机上间隔一段时间起个线程去做事情,手机会老是被唤醒,无法进入低功耗状态。
欧,对了,反正不止我一个应用,大家都这么搞啦,内存?内存我也多申请点,管其他应用会怎么样呢 《===普遍的想法

水果OSX新版就有让系统将多件操作堆积到一起进行的功能,比如磁盘写入、CPU唤起,可以省去很多电量
loki_lan
loki_lan
电量是硬伤,这是安卓平台的一大缺陷!
坏孩子
坏孩子
手机上又不止你一个程序,有意义吗
一只囧蟹
一只囧蟹
不绝对
antipro
antipro
要是老板也能看到这篇文章并且赞同就好了。
返回顶部
顶部