17

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

如何才能做到这一点?如何在不耗尽电池的情况下接收来自 Internet 的“中断”?

4

4 回答 4

24

当您在从 tcp 流中读取时被阻止,设备可以进入深度睡眠,并且当 tcp 流量进入时,它会短暂唤醒设备,一旦读入一个位,您就会启动唤醒锁,直到您收到整个传输然后释放它。

这是一个使用网络套接字的示例,我已经在后台运行了这个应用程序超过 12 个小时,没有对电池造成影响。 https://github.com/schwiz/android-websocket-example

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

于 2013-05-17T06:39:07.090 回答
12

几年来,我一直在没有唤醒锁的情况下在 Android 上使用长期有效的 TCP 连接。

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

现在设备已唤醒,接收进程也有一些时间来处理数据。现在,要么进程能够在设备重新进入深度睡眠之前这样做,要么设备将进入深度睡眠,同时暂停进程。这里重要的是数据不会丢失,它保留在内存中,并且该进程能够在设备下次离开深度睡眠时恢复处理数据的工作。当然,这意味着如果发送者等待对他的数据的答复,可能需要一些时间,直到他得到它。

一旦您的网络库通知您收到了新消息,您就可以使用唤醒锁定。但是如果你完成了,那么请确保正确处理锁,即确保它在某个时间点和每个代码路径中被释放。我个人从来没有经历过唤醒锁的需要,Android 设备总是足够长的时间来处理请求。但你的米数可能会有所不同。

于 2014-03-26T12:43:28.857 回答
1

所以这已经很老了,但我最终测试了@Flow 描述的行为,只是想确认在数据到达和设备唤醒之间有时会出现任意延迟。
我使用 tcpClient 实现和 mqtimplementation 进行了测试。这个想法是看看是否需要立即获得唤醒锁,因为这个延迟出现在我的 mqtt 实现中。
测试步骤:

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

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

  • 这种延迟有时可以在所有设备上看到(在 huaweip20light、HMD Global#Nokia 7.2、samsung#SM-N960F 上测试)
  • 这种延迟更可能发生在 HMD 设备更高的 api 上,并且是 android 建立的更严格的电池优化的受害者
于 2022-01-06T14:30:24.407 回答
-2

Google Cloud Messaging 可能是您正在寻找的:

http://developer.android.com/guide/google/gcm/index.html

于 2012-11-23T19:37:28.800 回答