【问题标题】:WP8 app resuming with sensorsWP8 应用程序使用传感器恢复
【发布时间】:2013-01-26 21:14:32
【问题描述】:

在我的 WP8 应用程序中,我使用所有传感器。加速度计、指南针(来自 Windows.Devices.Sensors 和 Microsoft.Devices.Sensors)和倾角计。 一切正常,直到我按下 Windows 按钮,然后按下 Back 按钮。 我得到一个带有 “Resuming...” 消息的全黑屏,但没有任何反应。一旦我得到一个异常(从 5 失败只有一次):

{System.Runtime.InteropServices.SEHException: External component has thrown an exception.
   at Microsoft.Devices.Sensors.SensorBase`1.PauseSensor()
   at Microsoft.Devices.Sensors.SensorBase`1.<>c__DisplayClass7.<.ctor>b__4(Object sender, NotificationCallbackEventArgs args)
   at Microsoft.Devices.Sensors.SensorCallback.MS.Internal.Interop.INotificationCallback.Pausing(XPauseType pauseType)
   at MS.Internal.Interop.NotificationService.NotificationPausing(XPauseType pauseType)
   at MS.Internal.FrameworkCallbacks.NotificationPausing(UInt32 pauseType)}

有人遇到过这个例外吗?

或者是否有在 wp8 应用程序生命周期中正确使用传感器的最佳实践?

谢谢

【问题讨论】:

    标签: windows-phone-8 sensors application-lifecycle


    【解决方案1】:

    这个问题比我想象的要复杂。我在这方面做了很多工作。我分享我的发现,因为我认为我的经验也可以帮助以后的其他人。

    我通过服务类使用传感器:这些类更新我的虚拟机,在虚拟机中我使用我的 DispatcherHelper 在 UI 上更新这些。我知道如果我想更新传感器的 valuechanged 事件中的 UI 绑定属性,我需要在事件处理程序中使用 dispatcherhelper 调用此更新,但我不知道如果它们与 VM 而不是 Views 通信时它们的行为如何。当我启动应用程序时,如果传感器具有新值,我在更新 UI 时没有任何问题。在这种情况下,我唯一的问题是,如果我想停用(按下 Windows 按钮)并激活(按下后退按钮)我的应用程序,我也不例外,我没有丢失调试会话,但只有一个带有“正在恢复”的黑页...”文本和运行进度条,什么也没发生。

    我错过的是跨线程/访问异常。如果我使用 UI 绑定数据执行此操作,则会引发异常,但在这种情况下不会。

    另一件事:加速度计(我有一个仅适用于加速度计的版本)适用于模拟器,但在设备上却不能。我认为模拟器试图通过返回值来模拟加速器,但不是以正确的方式(没有线程问题)。

    解决方案

    如果我在 UI 线程的事件处理程序中更新(使用我自己的 DispatcherHelper),一切正常。这是一个很好的经验教训,在与传感器和其他层/线程(VM、V)交互时要时刻注意。

    【讨论】:

    • 您能否解释一下如何在您的解决方案中将 Dispatcher 传递给 VM?谢谢。
    • 抱歉这么晚才回复。我有一个自己的小型调度助手类。具有注册 Dispatcher 的方法的单例类,Register(Dispatcher d) 和另一个检查调度程序的方法 void Invoke(Action a),如果不是 null,则调用 dispatcher.BeginInvoke(a),我调用 register 方法在我的引导程序类中。 UiDispatcher.Instance.Register(RootFrame.Dispatcher) 或者您也可以从 MainView 或您拥有 rootframe 调度程序的其他地方调用它。如果不清楚,我会在其他答案中发布。
    【解决方案2】:

    听起来确实像一个生命周期问题。

    您是否尝试过在 App.Deactivated 事件上从 Microsoft.Devices.Sensors 对传感器调用 SensorBase.Stop() 并在 App.Activated 事件上恢复使用 SensorBase.Start()?根据您的应用中有多少页面需要传感器访问,您甚至可以覆盖 OnNavigatedTo/OnNavigatedFrom 方法并使用这些方法。

    您不必这样做,但根据您的应用,这可能是个好主意。 (你的应用支持锁屏空闲执行吗?它有后台代理吗?它是否在后台运行时尝试获取传感器读数?)

    【讨论】:

    • 我调用了我的 Compass(来自 Microsoft.Devices.Sensors)Stop(),但经过一些调试后,我发现它永远不会完成。我知道我在 compass.Stop() 之后拥有的东西永远不会被调用,如果我让调试器在我从我的应用程序导航后运行它需要 1-2 分钟,但我得到一个 System.Runtime.InteropServices.SEHException (发生在未知模块中。但未在用户代码中处理)。看起来停止直到操作系统想要释放应用程序资源(-->终止阶段)才完成
    • 我之前也调用了 Stop(),但是我在 Caliburn.Micro 中的生命周期处理方面遇到了问题,并且从未调用过 Bootstrapper 中的 OnDeactivated。但是你有权利从 SensorBase 调用 Sensor 上的 Stop/Start。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    相关资源
    最近更新 更多