终止/挂起时,重大更改位置API的行为?


108

这是CLLocationManager文档中的部分,描述了具有startMonitoringSignificantLocationChanges的应用行为:

如果启动此服务,并且随后终止了您的应用程序,则当新事件到来时,系统会自动将应用程序重新启动到后台。在这种情况下,传递给应用程序委托的application:didFinishLaunchingWithOptions:方法的选项字典包含键UIApplicationLaunchOptionsLocationKey,以指示由于位置事件而启动了您的应用程序。重新启动后,您仍然必须配置位置管理器对象并调用此方法以继续接收位置事件。当您重新启动位置服务时,当前事件将立即传递给您的委托。此外,甚至在您启动位置服务之前,位置管理器对象的location属性也会使用最新的位置对象进行填充。

因此,我的理解是,如果您的应用终止(并且假设您不从applicationWillTerminate调用stopMonitoringSignificantLocationChanges),您将被UIApplicationLaunchOptionsLocationKey参数唤醒:application:didFinishLaunchingWithOptions。此时,您将创建CLLocationManager,调用startMonitoringSignificantLocationChanges并在有限的时间内进行后台位置处理。因此,我对此表示满意。

上一段仅讨论终止应用程序时发生的情况,而没有建议您暂停应用程序时的操作。didFinishLaunchingWithOptions的文档说:

该应用程序在后台跟踪位置更新,已被清除,现在已重新启动。在这种情况下,词典包含一个键,该键指示由于发生新的位置事件而重新启动了该应用程序。

建议您终止应用程序后,仅在启动应用程序(由于位置更改)时才收到此呼叫。

但是,《位置感知编程指南》中有关“ 重要更改服务”的段落说明如下:

如果您使该服务保持运行状态,并且随后您的应用程序被挂起或终止,则当新的位置数据到达时,该服务会自动唤醒您的应用程序。唤醒时,您的应用程序将被置于后台,并留出少量时间来处理位置数据。因为您的应用程序在后台,所以它应该做的工作最少,并且避免任何可能阻止其在分配的时间到期之前返回的任务(例如查询网络)。否则,您的应用程序可能会终止。

这表明如果您的应用已被暂停,则您将被位置数据唤醒,但未提及您如何被唤醒:

在撰写本文的过程中,我想我可能已经回答了我自己的问题,但是最好是由知识渊博的人来确认我的理解。

Answers:


80

自从我问了这个问题以来,我已经做了相当多的测试(大部分是在家庭和工作之间的火车上),并确认暂停的应用程序的行为与我在问题末尾所怀疑的一样。

也就是说,已暂停的应用程序被唤醒,您的应用程序委托没有收到任何回调,而是通过现有的CLLocationManagerDelegate接收了位置更新。您可以通过检查applicationState来检测到您正在后台运行,并且对于从挂起状态醒来进行位置处理的情况,可以做一些有限的工作。

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

我得出的结论是带有位置测试工具,欢迎您下载并试用。这是一个非常简单的应用程序,可让您通过用户界面打开重大更改和GPS更改API,并记录所有返回的响应。

注意:上一个答案中的第六点是不正确的。从挂起状态唤醒后,冻结干挂起的应用程序确实会收到CLLocationManagerDelegate回调。


1
在我的回答中剔除#6,以免混淆别人。
亚伦

具有讽刺意味的是,在进行重大更改时,我也感到同样的困惑。我仍然对如果关闭应用程序会发生什么感到怀疑。UIApplicationDelegate回调不会发生?是启动应用程序的正确方法。如果位置管理器尚未启动,如何在后台获取通知?(需要更多的研发时间)
darshansonde,2012年

非常感谢您提供的示例应用程序,这对我非常有用。我有一个问题:如果我在后台使用标准位置服务,而不是重要的服务,那么在终止后该应用也会重新启动吗?我在这里问这个问题详细,我会很高兴,如果你能减轻我:] stackoverflow.com/questions/12239967/...
aslisabanci


您知道终止应用程序需要多长时间吗?然后获取一个appDelegate回调?(是30分钟吗?2小时吗?5小时吗?)之所以这样问,是因为我已经设置了要监视的区域。尝试过多次以查看我的应用程序已启动,但只有一次必须重新启动该应用程序。其他时候是didExitRegion回调,但是我无法startLocationUpdates从那里通过回调,因为那不是通过应用程序启动的……
Honey

25

我的理解如下(我正在编写一个依赖于此API的应用程序,但尚未完全完成此组件以开始测试):

  1. 您的应用程序首次运行,您注册了startMonitoringSignificantLocationChanges,并提供了一个回调函数。当您的应用程序运行时,只要收到重大更改,它将调用该回调。
  2. 如果将您的应用程序置于后台,则UIApplication将收到applicationWillResignActive,其后是applicationDidEnterBackground
  3. 如果您的应用程序在后台挂起时被杀死,则不会收到通知。但是,如果您的应用程序在运行时被杀死(据我所知是前景或背景),您将有一段时间使用applicationWillTerminate。您不能通过此功能请求额外的背景时间。
  4. 尽管在后台被杀死,该操作系统仍会重新启动您的应用程序。如果您的应用只是由操作系统启动以进行更改,则将调用应用didFinishLaunchingWithOptions

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    将帮助您确定您是否从后台位置更改中回来了。

  5. 相反,如果您当前正在后台运行,并且您的应用由用户手动重新启动,则您将收到applicationWillEnterForeground,后跟applicationDidBecomeActive
  6. 不管发生了什么,重新启动应用程序时(除非由于后台任务而仍在后台运行,并且说该任务已开始监视更改),您都需要再次明确地告诉它再次启动startMonitoringSignificantLocationChanges,因为回调不是“冷冻干燥”后不再附着。是的,一旦从挂起状态恢复了某种位置处理程序后,只需在didUpdateToLocation中实现代码。

这就是我现在进行代码开发的过程。正如我之前提到的,我还没有准备好在设备上进行测试,因此我无法确定我是否正确解释了所有内容,因此评论者可以随时进行纠正(尽管我已经在话题)。

哦,如果运气不好,您发布的应用程序可以执行我想做的事情,我可能会哭:)

祝好运!


1
@Tegeril +1感谢您的回答。我开始听到on的声音。:)我很惊讶应用程序从暂停状态开始需要重新调用startMonitoringSignificantLocationChanges。您是否有描述该文档的doco链接?我的理解是,从挂起状态加载将实例化所有对象,就像它们在应用程序挂起时一样。因此,我希望重大更改请求生效。
RedBlueThing 2010年

您可能在谈论这个?“重新启动后,您仍必须配置位置管理器对象并调用此方法以继续接收位置事件”,但我认为这是指您的应用从终止状态(通过位置事件)启动的情况。这基本上是我的问题的根源,“中止的案件会发生什么?”。
RedBlueThing 2010年

开发论坛上的Morgan Grainger建议:“您需要创建一个CLLocationManager,设置一个委托,并在应用程序启动时调用startMonitoringSignificantLocationChanges,否则Core Location将无处交付更新。” 在重新启动应用程序的上下文中,无论处于终止状态还是挂起状态。从“启动startMonitoringSignificantLocationChanges之后重新启动应用程序,现在是什么?”
亚伦

我同意即使在该论坛帖子的上下文中这仍然可能是模糊的(张贴者正在讨论从后台唤醒,但是Morgan使用了更一般的重新启动应用程序)。我仍然认为,如果要使用重大更改功能,则需要在应用程序重新启动时再次致电进行监视。如果您要启动后台任务并使用标准的位置服务和GPS功能进行更新,则可以选择该方法。我不认为您需要在每次启动时都进行重大更改来重新注册,以便再次启动。
亚伦

1
我很高兴从中得出确定的
亚伦

1

如果由于位置更改而将应用程序从暂停状态中唤醒,则应用程序将在后台状态下启动。

所有对象都将处于活动状态,您将在现有委托中收到位置更新。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.