Android: 使用 IntentService 获取快速数据
Android: Using an IntentService for rapid data
我有一个 Android 应用程序,它将通过蓝牙 (BLE) 接收快速数据。数据将以 50-100 Hz 的频率从远程传感器设备到达 Android 智能手机上的专用服务(Nordic nRF BLE 管理器)。我想以全速将数据交给单独的服务来对其进行计算分析。如果我使用 IntentService 进行分析,这意味着每 10 毫秒就会有一个意图。我确信每个 Intent 都有很大的开销,我怀疑它是为这么多数据而设计的。但是我读到的所有内容都表明这是最简单的解决方案。这是正确的方法吗?谢谢
IntentService 嵌入了传入 Intent 队列,因此,如果您处理 Intent 的速度比它们到达的速度慢,也可以这样做。
但是,我会使用 HandlerThread 将 Message 中的传入数据发布到它上面。它也有嵌入式消息队列,但没有开销,就像创建 IntentService 一样。
另一种方法 - 使用普通服务并使用 RxJava 库处理背压。
首先你需要决定你是否需要实时行为。数据通过 BLE 实时接收,但您真的需要实时处理吗?如果您正在计算的分析不需要实时进行,那么接收数据、存储数据并稍后处理就可以了。
如果您确实需要实时数据处理,那么 IntentService
并不是一个合适的设计选择。
如果您不需要实时数据处理,那么 IntentService
可以工作,但从性能的角度来看不是最佳的。
会有两次开销。
您自己找到的第一个 - 发送意图承担一些额外的开销,因为 OS 需要 "route" 服务的意图。
第二个将与启动和停止相关联 IntentService
。如果意图到达之间的时间间隔小于 onHandleIntent()
到 return 所花费的时间,则系统将为每个意图启动和停止 IntentService
。这个开销比第一个高得多。
因此,即使 IntentService
可以在这种情况下工作,恕我直言,您不应该使用这种方法。
解决此问题的最佳方法是使用绑定 Service
。从 BLE 接收器绑定到它并使用常规方法调用发送数据。缺点是您需要自己实现两个功能:
- 需要处理的数据阻塞队列
- 将处理卸载到后台线程的逻辑
编写此逻辑并非易事,但如果您的应用程序是一个严肃的项目,那么恕我直言,这是唯一正确的做法。您可以从 IntentService
.
的源代码中复制粘贴线程逻辑
提醒一句:你必须意识到过度的内存消耗。例如:如果您使用单个后台线程进行处理,并且传入数据的速率高于处理速率,那么您的队列将不断增长。在这种情况下,如果有足够的时间,您的应用程序将因 OutOfMemory 异常而崩溃(IntentService
也可能发生)。
如果发生这种情况,您需要执行以下任一操作:
- 使用多线程进行后台处理
- 将数据存储到 SQLite 中(但 SQLite 可能会过度增长)
- 删除一些数据
我有一个 Android 应用程序,它将通过蓝牙 (BLE) 接收快速数据。数据将以 50-100 Hz 的频率从远程传感器设备到达 Android 智能手机上的专用服务(Nordic nRF BLE 管理器)。我想以全速将数据交给单独的服务来对其进行计算分析。如果我使用 IntentService 进行分析,这意味着每 10 毫秒就会有一个意图。我确信每个 Intent 都有很大的开销,我怀疑它是为这么多数据而设计的。但是我读到的所有内容都表明这是最简单的解决方案。这是正确的方法吗?谢谢
IntentService 嵌入了传入 Intent 队列,因此,如果您处理 Intent 的速度比它们到达的速度慢,也可以这样做。 但是,我会使用 HandlerThread 将 Message 中的传入数据发布到它上面。它也有嵌入式消息队列,但没有开销,就像创建 IntentService 一样。 另一种方法 - 使用普通服务并使用 RxJava 库处理背压。
首先你需要决定你是否需要实时行为。数据通过 BLE 实时接收,但您真的需要实时处理吗?如果您正在计算的分析不需要实时进行,那么接收数据、存储数据并稍后处理就可以了。
如果您确实需要实时数据处理,那么 IntentService
并不是一个合适的设计选择。
如果您不需要实时数据处理,那么 IntentService
可以工作,但从性能的角度来看不是最佳的。
会有两次开销。
您自己找到的第一个 - 发送意图承担一些额外的开销,因为 OS 需要 "route" 服务的意图。
第二个将与启动和停止相关联 IntentService
。如果意图到达之间的时间间隔小于 onHandleIntent()
到 return 所花费的时间,则系统将为每个意图启动和停止 IntentService
。这个开销比第一个高得多。
因此,即使 IntentService
可以在这种情况下工作,恕我直言,您不应该使用这种方法。
解决此问题的最佳方法是使用绑定 Service
。从 BLE 接收器绑定到它并使用常规方法调用发送数据。缺点是您需要自己实现两个功能:
- 需要处理的数据阻塞队列
- 将处理卸载到后台线程的逻辑
编写此逻辑并非易事,但如果您的应用程序是一个严肃的项目,那么恕我直言,这是唯一正确的做法。您可以从 IntentService
.
提醒一句:你必须意识到过度的内存消耗。例如:如果您使用单个后台线程进行处理,并且传入数据的速率高于处理速率,那么您的队列将不断增长。在这种情况下,如果有足够的时间,您的应用程序将因 OutOfMemory 异常而崩溃(IntentService
也可能发生)。
如果发生这种情况,您需要执行以下任一操作:
- 使用多线程进行后台处理
- 将数据存储到 SQLite 中(但 SQLite 可能会过度增长)
- 删除一些数据