这是在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();
}
我可以导航到其他页面并返回,预览可靠地运行。我遇到了以下情况的问题:
在上述每个操作(和/或它们的组合)之后,当我的应用程序返回时,预览会在显示的最后一帧被冻结。
如果用户然后导航到另一个页面然后返回到MainPage,则预览会再次开始运行而不会出现问题,因此这让我相信我只需要在从其中一个回来之后停止/启动预览以上情景。
我尝试订阅App.Suspending
和App.Resuming
事件,但这些事件并未触发。我错过了什么?
答案 0 :(得分:4)
您必须结合导航事件(在页面之间导航时)使用App.Suspending
和App.Resuming
(针对您所描述的情况)。点击开始,按住返回或使用搜索(当应用程序被暂停时)调用OnNavigatingFrom
事件,但是当您恢复应用时,OnNavigatedTo
不被调用 - 只有在您导航时才会调用此事件。因此,在您的情况下,当您点击开始时,预览会停止,当您返回时,它不会重新开始。 A refference to MSDN:
注意在Windows Phone上,应用程序暂停时会调用OnNavigatedFrom()。恢复应用程序时不会调用OnNavigatedTo()。
另一件事是,要正确调试应用程序,您必须在Visual Studio中使用调试位置选项卡的生命周期事件 - 当您对应用程序进行调试时,它没有被暂停,但是当你正常运行你的应用程序时,它会在你点击 Start 之后暂停。
另请注意,可以将应用程序置于 Not Running 状态。有关Lifecycle at MSDN的更多信息。
答案 1 :(得分:1)
您描述的方案应该触发Window.Current.VisibilityChanged
事件,您可以使用VisibilityChangedEventArgs.Visible
传递到事件处理程序,以便在不可见时清除预览,并在可见时初始化预览。您可以在Page \ UserControl的Loaded \ Unloaded处理程序中订阅\取消订阅Window.Current.VisibilityChanged
事件。
Suspend / Resume生命周期事件不充分的原因是因为上面提到的场景在某个时间没有确定性地调用这些事件,因为OS只会根据可以随OS更改的内部策略挂起应用程序发布更新。
另外,我会避免使用导航处理程序,而是依赖于Loaded \ Unloaded处理程序,如果你不得不将CaptureElement移动到它自己的UserControl中而不是在Page和Page,那么它将允许初始化\ cleanup正常发生。避免WP将调用OnNavigatedFrom而不调用OnNavigatedTo进行suspend \ resume的情况(将始终按顺序调用Loaded \ Unloaded)。