MediaCapture + CaptureElement生命周期/导航管理
这是在Windows Phone 8.1商店应用程序中。 我的MainPage
有一个CaptureElement
来显示来自MediaCapture
对象的预览流。 对于应用程序内的导航(页面之间),这很有效:
MediaCapture mc; protected override async void OnNavigatedTo(NavigationEventArgs e) { mc = new MediaCapture(); await mc.InitializeAsync(); preview.Source = mc; await mc.StartPreviewAsync(); } protected override async void OnNavigatedFrom(NavigationEventArgs e) { await mc.StopPreviewAsync(); }
我可以导航到其他页面并返回,预览可靠地运行。 我遇到了以下情况的问题:
- 用户按下Windows按钮,然后按后退按钮
- 用户按下Windows按钮,然后使用任务切换器返回我的应用程序
- 用户按下搜索按钮,然后按下后退按钮
- 用户按下电源按钮,然后再次按下并向上滑动以解锁设备
- 用户按住后退按钮进入任务切换器,然后再次点击我的应用程序
在上述每个操作(和/或它们的组合)之后,当我的应用程序返回时,预览将冻结在显示的最后一帧。
如果用户然后导航到另一个页面然后返回到MainPage,则预览会再次开始运行而不会出现问题,因此这让我相信我只需要在从上述场景之一返回后停止/启动预览。
我尝试订阅App.Suspending
和App.Resuming
事件,但这些都不会在这些情况下触发。 我错过了什么?
您将不得不使用App.Suspending
和App.Resuming
(对于您描述的情况)与导航事件的组合(在页面之间导航时)。 当您点击“ 开始” ,“保持后退”或“使用搜索” (当应用程序被暂停时)时会调用OnNavigatingFrom
事件,但是当您恢复应用程序时, 未调用OnNavigatedTo
– 仅在您导航时才会调用此事件。 因此,在您的情况下,当您点击“ 开始”时 ,预览会停止,当您返回时,它不会重新开始。 对MSDN的引用 :
注意在Windows Phone上,应用程序挂起时会调用OnNavigatedFrom()。 应用程序恢复时不会调用OnNavigatedTo()。
另一件事是,要正确调试应用程序,您必须使用Visual Studio中的调试位置选项卡的 生命周期事件 – 当您对应用程序进行调试时,它不会被暂停,但是当您正常运行应用程序时,它会被暂停点击开始后 。
另请注意,App可以进入Not Running状态。 有关MSDN生命周期的更多信息。
您描述的场景应该触发Window.Current.VisibilityChanged
事件,您可以使用传递到事件处理程序的VisibilityChangedEventArgs.Visible
在不可见时清除预览,并在可见时初始化预览。 您可以在Page \ UserControl的Loaded \ Unloaded处理程序中订阅\取消订阅Window.Current.VisibilityChanged
事件。
暂停/恢复生命周期事件不充分的原因是因为上面提到的方案在某个时间没有确定性地调用这些事件,因为操作系统将仅根据可能随操作系统发布更新而更改的内部策略来暂停应用程序。
另外,我会避免使用导航处理程序,而是依赖于Loaded \ Unloaded处理程序,如果你不得不将CaptureElement移动到它自己的UserControl而不是在Page中,那么将允许初始化\ cleanup正常发生并避免这种情况WP将调用OnNavigatedFrom而不调用OnNavigatedTo进行suspend \ resume(将始终按顺序调用Loaded \ Unloaded)。