39

我一直在为使用持久套接字的 Android 设备的自定义推送通知解决方案做一些测试。我想分享我的发现并验证结果。

简单描述
应用程序运行前台服务并与服务器建立连接,并通过积极 ping(@ 10 秒间隔)维持该连接。如果检测到连接已失效,则应用程序会无限期地尝试重新连接。服务器通过双工通道发送通知。

测试 1:

Pinging is done using a timer at 10 second intervals.
Server sends notification every minute.
Applications acquires wifi and wake locks.
Duration : 8 hours
Battery loss : ~14%

测试 2:

Pinging is done using AlarmManager at 10 second intervals.
Server sends notification every minute.
Application acquires only a wifilock
Duration : 8 hours
Battery loss : ~7%

假设:传入的网络数据包会自动唤醒 CPU,因此不需要唤醒锁。使用 AlarmManager 来 ping(而不是计时器)意味着我们不需要唤醒锁。

移除那个唤醒锁似乎真的对电池有帮助。令人惊讶的是,对这两种解决方案的积极 ping 并没有像我预期的那样影响电池寿命。(我们进行了许多其他测试,包括应用程序仅持有一个 wifilock 并且什么也没做,这导致同期电池损耗约为 4% 到 5%)

由于应用程序能够成功发送所有 ping 请求并接收所有传入消息,我相信我的假设是正确的。但我很想得到任何专家的确认。

还有一个问题: 如果应用程序改为监听传入连接。在这种情况下,我需要保持唤醒锁,对吗?传入连接不会唤醒 CPU?我们不会走这条路,只是想确认一下。

另外,请不要推荐GCM,公司政策已经排除了。

谢谢。

4

1 回答 1

15

由于对这个问题有一些兴趣并且没有确认,我现在就回复。自测试完成以来已经有一段时间了,并且已经创建并严格测试了生产级解决方案。移除唤醒锁仍然对电池有帮助,并且没有发现其他问题,例如缺少 ping 请求或传入通知,因此这是我在上述假设下收到的唯一验证。

需要注意的其他事项:

  • 在用于 ping 警报的 BroadcastReceiver 的 OnReceive 方法中,如果您不直接调用套接字(生成新线程或意图),您将需要保持唤醒锁,直到 ping 请求完成。Android 仅在 OnReceive 返回之前持有唤醒锁,之后 CPU 可能会在 ping 完成之前休眠(但很少见)。

  • 如果通知很敏感,请使用高性能 Wifi Lock 。

  • 还有另一个影响解决方案的设备特定问题,在此处进行了介绍。

更新

Android 5.1 遇到以下问题:Android 问题

更新 2

需要围绕 Android 6.0 的打盹模式编写代码:打盹模式

于 2013-10-29T17:01:29.807 回答