如何使Android设备保持与互联网的TCP连接而无需唤醒锁定?

17

我希望我的应用程序能通过移动连接连接到服务器,同时允许设备进入睡眠模式。我期望当IP包到达时它会自动唤醒。

如何实现这一点? 如何在不耗尽电池的情况下接收来自互联网的“中断”?


我认为一个服务可以解决你的问题,但会消耗电池。它可以在后台线程上运行,定期检查包。 - Balázs Édes
我希望我的设备能够在线上(例如从XMPP接收消息),而不会显著增加电池的使用量。 - Vi.
4个回答

24

当你在从TCP流中读取数据时被阻塞时,设备可以进入深度睡眠状态,当TCP流量到达时,它会短暂地唤醒设备,只要读取了一点数据,就开始一个WakeLock,直到接收到整个传输,然后释放它。

这里有一个关于WebSockets的示例,我在后台运行了超过12小时,并没有影响电池寿命。 https://github.com/schwiz/android-websocket-example

客户端在这里,阻塞式读取在start方法中。 https://github.com/schwiz/android-websockets/blob/master/src/com/codebutler/android_websockets/HybiParser.java


1
它将会简短地唤醒设备。它是否可靠(包括跨 NAT)?它适用于所有 Android 版本吗? - Vi.
这不是真的。在您的项目中,您持有部分唤醒锁定,因此CPU保持活动状态。 - pepyakin
4
只有当数据实际传输时,通信之间才没有唤醒锁。我让程序运行了12个小时以上,即使进行了所有的保持连接ping操作,仍然只记录了少于3秒的唤醒锁时间。这恰好是我所说的,并且事实上是正确的。 - Nathan Schwermann
我正在尝试使用这个演示,但它并没有像应该那样工作。消息不会实时更新(只有在重新加载应用程序或网页时才会更新)。有人让它正常工作了吗? - Arthur
1
@schwiz 嗯,除了“map”部分之外,一切都正常。我已经用“for”循环替换了“map”部分,所以现在一切都完美了!谢谢! - Arthur
显示剩余7条评论

12

我已经在Android上使用长连接TCP连接数年了,而且没有唤醒锁定。

我的经验是,当数据到达TCP连接并且设备处于深度睡眠状态时,设备会被唤醒至少一小段时间。有时唤醒设备可能需要长达约2分钟的时间,但通常只需要几秒钟。

现在设备已经唤醒,接收进程有一些时间来处理数据。现在,无论是进程在将设备放回深度睡眠之前能够完成处理数据,还是设备将进入深度睡眠以挂起进程,此时重要的是数据不会丢失,它仍然存储在内存中,进程能够在设备离开深度睡眠后恢复处理数据的工作。当然,这意味着如果发送方等待数据的答复,可能需要一些时间才能得到答复。

当您的网络库通知您接收到新消息时,您可以立即获取唤醒锁。但是,如果您这样做,请确保正确处理锁定,例如确保在某些点和每个代码路径上都释放它。就我个人而言,我从未感到需要唤醒锁定,Android设备总是足够长时间处于唤醒状态来处理请求。但是,您的情况可能会有所不同。


1

这个问题很老了,但我最近测试了@Flow描述的行为,并想确认一下,有时数据到达和设备唤醒之间似乎存在任意延迟。

我使用了tcpClient实现和mqttimplementation进行了测试。我的想法是看看是否需要立即获取wakelock,因为这种延迟出现在我的mqtt实现中。

测试设置:

  • 我们有两个服务,一个运行tcpclient,另一个在不同应用程序中运行mqttclient
  • 两个服务在相同的手机上以相同的权限在后台运行。
  • 服务器在两种情况下都发送“ping”消息。
  • 我们的客户端实现尽快获取wakelock并读取当前日期。
    • 对于tcpclient,这是瞬间完成的。
    • 对于mqttclient,只有在通过网络库传播到达的数据后才能获取wakelock。
  • 我们发送一个包括读取日期的响应pong消息
    • 此发送发生在释放wakelock之后,以查看是否进一步延迟了响应时间。
  • 服务器记录到达和读取日期的传入消息

在这两种实现中,似乎有时会出现任意延迟来调用我们的代码。这使得最有可能存在设备唤醒的延迟,而不是获取wakelock的延迟。

  • 这种延迟有时可以在所有设备上看到(在huaweip20light、HMD Global#Nokia 7.2、samsung#SM-N960F上进行了测试)
  • 这种延迟似乎更可能发生在HMD设备上,API较高,并受到安卓更严格的电池优化的影响。

-2

我想要拿一个现有的应用程序(例如Jabiru),并“神奇地”使其不会耗尽电池(以增加请求和通知之间的延迟为代价)。 - Vi.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接