【问题标题】:Running Android service for infinite time无限时间运行 Android 服务
【发布时间】:2011-10-13 17:16:37
【问题描述】:

我有一个在后台运行的位置服务,并使用位置管理器每 30 秒向我的服务器发送纬度和经度值。我希望此服务无限运行,直到用户停止服务。但我观察到的是几个小时后,服务消失了,因为它达到了 30+ mb。我想知道如何让它在不被用户停止的情况下运行?

我的一些观察(如果我错了,请纠正我): 在分配跟踪器中,大部分占用内存的对象都是位置管理器对象。 在堆中,当我导致 gc 时,我的对象分配的内存正在消失,所以我想没有内存泄漏。 在应用程序--> 运行服务中,我没有看到任何服务运行了 4 个多小时。所以我想做的事情是不可能的?

非常感谢任何帮助/建议。

提前致谢。

【问题讨论】:

  • 如果你想让它运行无限长的时间,那将很难测试。 :)

标签: android service location


【解决方案1】:

我不确定为什么您的服务开始占用超过 30 兆字节,但您可能会以某种方式泄漏内存。

但最终,您的设计存在缺陷。您能做的最好的事情是:

  1. 使用 PendingIntent 方法registerLocationUpdates 注册位置更新。您可以在此处指定更新之间的 minTime。
  2. 如果您需要每 30 秒精确地发送一次位置更新,您还可以向 AlarmManager 注册一个 PendingIntent 以每 30 秒发送一次意图。
  3. 让这个 PendingIntent 启动一个 IntentService。
  4. 让 IntentService 将位置数据发送到您的服务器。
  5. 当用户停止您的应用程序时,只需在 LocationManager(可能还有 AlarmManager)中注销您的 PendingIntents。

【讨论】:

  • 感谢您提供详细信息。我将执行第 1 步并更新您的进展情况。但是你认为这会让我的服务一直运行吗?
  • 事实是,您的服务不需要一直运行。这样做的目的是让 IntentService 每 30 秒启动一次以发送到您的服务器。完成发送到您的服务器后,该服务将关闭。这是实现您正在尝试做的最“友好”的方式。
  • 嗨贾斯汀,我用过这个。 public void requestLocationUpdates 以 LocationListener 监听器作为最后一个参数。和你说的有什么区别?我在我的 onHandleIntent 方法中只有一次这个寄存器(以前我每 30 秒做一次,我相信这可能是我的内存泄漏的原因)并等待我的调试器点击 onLocationChanged 但它从未到达那里。但是我的 getlastknownlocation 方法给了我不同的 lat 和 long 值。我相信只有在它到达 onLocationChanged 方法之后,它才会有不同的纬度和经度值,对吧?
  • 我指出您应该使用的不同之处在于 PendingIntent 用于接收您的位置数据,而不是通过 LocationListener 接收回调。每当您的设备接收到新位置时,getLastKnownLocation 应该会更新。据我所知,该方法与您的特定位置侦听器无关。如果返回的位置发生变化,则您的 GPS 位置正在以某种方式更新,因此您知道这是可行的。
  • 贾斯汀,我已经实现了pendingIntent 和位置更新工作,就像魅力一样。我在 onDestroy 方法中取消了我的 pendingIntent,但如果我强行停止我的应用程序,onDestroy 方法不会被调用,并且 pendingIntent 保持活动状态并更新位置。关于如何解决这个问题的任何建议?
【解决方案2】:

我有一个在后台运行的定位服务,并使用定位管理器每 30 秒向我的服务器发送纬度和经度值。

请允许用户选择投票周期,包括“从不投票”。

另外,请注意这会严重影响用户的电池。

我希望此服务无限运行,直到用户停止服务。

这是不可能的。您可以通过startForeground() 获得最接近的信息,但即使这样也不能保证您的服务将永远存在。

此外,这在 Android 中是一种严重的反模式。用户讨厌应用程序试图永远运行,这就是我们必须与任务杀手等竞争的原因。

但我观察到的是几个小时后,服务消失了,因为它达到了 30+ mb。

在保持 GPS 开启且设备始终处于唤醒状态的几个小时内,您用户的电池将耗尽,此时您的服务和其他一切都将消失。

关于内存,如果您认为您正在泄漏内存,请使用 MAT 追踪泄漏。

【讨论】:

    【解决方案3】:

    您为什么不以编程方式发出 gc - 比如每小时?

    我不知道你想做什么是不可能的。我想这应该是可能的。 让我疑惑的是:为什么 VM 不启动 gc 而是崩溃了?

    也许实际上存在内存泄漏问题?

    Avoiding memory leaks-blogentry 可能会给出一些提示。

    如果你给我们一些你的代码,也许有人可以给你更复杂的建议?

    【讨论】:

    • 您几乎不应该进行手动 GC 收集。 GC 足够聪明,可以在必要时执行收集。只有极少数情况下进行手动 GC 是个好主意。
    • 我同意。但在这种情况下,这将是让它运行几个小时的“第一种方法”。我猜他在某个地方有一些泄漏。
    • 感谢您的提示,菲尔多。我以编程方式尝试了 gc,但正如贾斯汀所说,这并不能解决问题,我觉得系统 gc 比手动 gc 更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多