2013-03-16 71 views
6

我正在构建一个应用程序,它将定期监视电池状态,wifi连接和位置数据,并将结果写入文件(并稍后将它们发送到服务器)。应该禁用安装应用程序监视 - 但启用它的用户应该在重新启动后继续。大量的阅读后,我已经意识到我已经基本2个选择:Android设计:背景长时间运行服务或AlarmManager?

  • 子类Service和我的活动火它关闭。将它设置在前景,STICKY和什么不是,并希望它不会被android杀死 - 并注意如果android重新创建它(实际上应该有3个服务,因此它们之间的同步可能会混乱)。在服务中启动一个线程(无需执行程序,我猜),并有Thread.sleep(REGULAR_INTERVAL)。唤醒,收集数据写入文件。广播收集到的信息并将其显示在我的活动中(如果它恰好在运行)(它将注册一个广播接收器)。冲洗并重复while(true)。有办法打断这个
  • 我的活动有注册一个PendingIntent与AlarmManager - 这将运行每个REGULAR_INTERVAL。我还没有深入研究过这种方法的技术细节 - 但我希望我能够让这个PendingIntent创建并运行一个IntentService(这似乎是一条可行的路线 - 让Thread机制免费以及关闭在其自己的)。这种方法的一些骨架代码将受到欢迎。

我想我必须注册在这两种情况下启动接收器检查共享偏好(已经做到了这一点),并在情况1启动服务(S),而在情况2寄存器的报警事件的接收器并设置警报管理器 - 这是我需要一些骨架代码的部分。

所以 - 在我开始构建之前 - 这将是首选方法?

在回顾 - 应用程序应该监视一些手机属性,并将它们写入文件,直到用户选择关闭它。

+0

你的用户或许会杀了你,如果你保持一个'Service'活着连续排水他们的手机电池只是聚集在一定的时间间隔圆顶数据。如果需要,可以使用第二种方法,带有带额外WakeLocks的'IntentService'(查看CommonsWare的'WakefullIntentService')。 – Luksprog 2013-03-16 16:06:12

+0

@Luksprog:谢谢 - 我需要锁吗?在接收报警的广播接收机中(仍在研究如何实现)? – 2013-03-16 16:10:44

+0

为什么是反面投票? – 2013-03-16 21:11:18

回答

6

,而在情况2注册的报警事件的接收器,并设置报警经理了

您的接收器将已经通过清单进行登记。

这将是首选方法?

AlarmManager,假设REGULAR_INTERVAL通常很长(例如几分钟)。理想情况下,该间隔是用户可配置的。

如果你打算这样做,即使该设备是睡着了,你的选择#1根本不会工作,除非你始终保持WakeLock,这将导致你的用户想拍摄你的脸用霰弹枪。

这种方法的一些骨架代码将受到欢迎。

Here is a sample app演示使用的AlarmManager用于非_WAKEUP报警(即,您只需要这些事件,而该设备已经醒了因其他原因发生)。

Here is a sample app演示使用AlarmManager_WAKEUP报警,使用my WakefulIntentServiceWakefulIntentService(或类似的东西)是必要的,因为AlarmManager不会让设备保持非常长的时间(只需要足够长的时间,以达到BroadcastReceiveronReceive()),所以您需要采取额外措施来保持设备足够长的时间以待您工作。 理论上,你的工作可能足够快,只需要在的BroadcastReceiver,避免需要混乱WakefulIntentService。但是,您将每次执行磁盘I/O,理想情况下不应在主应用程序线程上执行,其中onReceive()被调用。而且,当你去上传你的数据时,你可能需要一个WakefulIntentService然后,无论如何,如果你想在后台做这件事。

+0

谢谢 - 为什么注册BroadcastReceiver在清单(而不是启动一个 - 这必须在那里)?这是否意味着它会一直被注册 - 导致一些开销? BootReceiver - >'是否启用了监视? (为报警注册一个接收器;设置报警):返回似乎更经济。此外,AlarmReceiver将运行在我的主UI线程中?当我的活动(只显示收集的数据并允许启用/禁用监控)正常时,情况就会如此 - 不是吗?否则就不会有UI线程(或者它不会有所作为) - 我错了吗? – 2013-03-16 16:25:59

+0

@Mr_and_Mrs_D:“为什么要在清单中注册BroadcastReceiver” - 否则,您需要随时保留一个组件(例如Service),这是切换到“AlarmManager”后的一个要点。你不* *想要一直占用记忆。 “这是不是意味着它会一直注册 - 导致一些开销?” - 它只会被你的'AlarmManager'使用。 “另外AlarmReceiver将在我的主UI线程中运行?” - 在主应用程序线程上调用'BroadcastReceiver'的'onReceive()'。 – CommonsWare 2013-03-16 16:28:09

+0

@Mr_and_Mrs_D:“否则不会有UI线程” - 总是有一个“UI线程”,更准确地称为“主应用程序线程”。如果您在主应用程序线程上花费了太多时间,即使使用'onReceive()',Android也会终止您的操作。 – CommonsWare 2013-03-16 16:29:11

0

根据循环任务的长度,您可以选择几种方法之一。这个问题讨论他们 - Scheduling recurring task in Android

当任务睡眠时间是15分钟或更长的时间使用AlarmManager很方便。该模式是众所周知的。

+0

@CommonsWare:我有类似的情况来执行一些任务(GPS定位),间隔1分钟。我在我的主要活动中使用Handler,它将如何影响我的应用程序 – Tushar 2013-06-01 19:20:44