Windows runtime MediaCapture和窗口可视性已更改

Windows runtime MediaCapture和窗口可视性已更改,windows-runtime,windows-phone-8.1,winrt-xaml,Windows Runtime,Windows Phone 8.1,Winrt Xaml,[问题] 在Windows Phone 8.1上,在用户离开应用程序和OnSuspended事件触发之间到底发生了什么?我在管理该范围内的对象方面遇到了问题,尤其是MediaCpture对象 为了更好地解释问题,以下是场景: 用户在一个页面上,视频预览被压缩到CaptureElement 用户点击开始按钮 用户点击“后退”按钮,返回带有中断MediaCapture的页面 使用WinRT时,不会出现隐藏事件,从中导航不会触发,除非您要转到同一帧中的另一页。经过一些调查,我发现触发的唯一事件是Win

[问题]

在Windows Phone 8.1上,在用户离开应用程序和OnSuspended事件触发之间到底发生了什么?我在管理该范围内的对象方面遇到了问题,尤其是MediaCpture对象

为了更好地解释问题,以下是场景:

  • 用户在一个页面上,视频预览被压缩到CaptureElement
  • 用户点击开始按钮
  • 用户点击“后退”按钮,返回带有中断MediaCapture的页面
  • 使用WinRT时,不会出现隐藏事件从中导航不会触发,除非您要转到同一帧中的另一页。经过一些调查,我发现触发的唯一事件是Window.Current.VisibilityChanged

    当页面被导航到并在导航自时取消钩住(参见下面的ex2)时,我已经开始钩住它。在事件内部,我检查用于指示应用程序是否隐藏或显示的参数,并相应地进行处置/初始化(参见下面的ex.1)

    [问题]

    但是,这只适用于附加的调试器。如果我在未连接调试器的情况下执行此操作,它不会重新初始化,经常会使相机崩溃,我必须重新启动设备

    代码示例1(注意:e.Visible==false表示离开应用程序,true表示返回)

    async void Current\u可视性已更改(对象发送方,可视性更改Deventargs e)
    {
    如果(!e.Visible)//表示退出应用程序
    {
    wait DisposeAll();//清除MediaCapture和CaptureElement
    }
    其他的
    {
    如果(mediaCaptureManager!=null)等待DisposeAll();
    等待初始化();//再次设置摄像机
    }
    }
    
    示例2(与事件挂钩)

    受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
    {
    Window.Current.VisibilityChanged+=当前\u VisibilityChanged;
    this.navigationHelper.OnNavigatedTo(e);
    }
    受保护的异步重写无效OnNavigatedFrom(NavigationEventArgs e)
    {
    Window.Current.VisibilityChanged-=当前\u VisibilityChanged;
    this.navigationHelper.OnNavigatedFrom(e);
    }
    
    [更新:分辨率]

    不要使用VisibilityChanged,而是挂接到页面构造函数上的Window.Current.Activated。调试器完全分离后,激活的事件将在WindowActivateEventArgs中提供WindowActivationState参数。像这样:

    private async void CurrentOnActivated(object sender, WindowActivatedEventArgs e)
    {
        if(e.WindowActivationState == CoreWindowActivationState.Deactivated)
        {
            //dispose MediaCapture here
        }
        else if(e.WindowActivationState == CoreWindowActivationState.CodeActivated || e.WindowActivationState == CoreWindowActivationState.PointerActivated)
        {
            //initialize MediaCapture here
        }
    }
    

    我不确定是否使用挂起/恢复事件更合适。请注意,在这种情况下,您必须正确地调试它-它

    至于代码-将事件挂接到OnNavigatedTo/OnNavigatedFrom中不是一个好主意-当操作系统挂起应用程序并且您正在使用SuspendionManager时,将调用OnNavigatedFrom,但当您返回应用程序(恢复应用程序)时,将不会调用OnNavigatedTo

    在这里使用窗口事件也可以,但为什么不在构造函数中的某个地方订阅一次呢它的窗口很宽,所以在手机中只有一个窗口,代表应用,然后订阅一次。在这种情况下,您可以在窗口中添加一行来识别当前页面,如果该页面包含mediacapture,则可以进行处置(创建类似内容)。然后,您还可以在导航事件中处理/初始化,以防用户不离开您的应用程序而只是导航。

    请参阅中的“我的答案”。使用
    Window.VisibilityChanged
    和页面\UserControl加载\卸载处理程序结合使用,我相信应该可以解决您的问题


    使用
    Window.Activated
    不如
    Window.VisibilityChanged
    ,因为Activated与可视性相关,而VisibilityChanged只与可视性相关。用于显示具有焦点的预览不适用。由于Windows Phone上的Windows应用商店应用程序只能显示一个窗口,因此,如果您的应用程序成为通用应用程序并在Windows 8+Modern shell(可以显示具有快照窗口功能的多个应用商店应用程序)或Windows 10桌面上运行,则两者的使用没有区别(可支持多个商店应用程序同时显示)当用户更改应用程序的焦点时,您不会希望停止预览,但您的应用程序仍在显示。

    我使用导航从VisibilityChanged挂起和取消挂起的原因是,我只希望此视图中出现此行为。VisibilityChanged事件也非常适合我的需要(我已确认w/MS这是检测应用程序何时关闭的唯一方法,但在调用OnSuspended之前)。我的问题仅仅是MediaCapture对象。它没有得到正确的处理。我不能使用OnSuspending的原因是它并不总是立即启动。因此,如果用户点击“主页”按钮,然后立即返回,相机就坏了,但应用程序从未挂起。@LanceMcCarthy你能为整个应用程序订阅VisibilityChanged吗如果Window.Current.Content(第页),则检查事件内部包含您的视图或其他?可能已找到解决方案。App.Current.Resuming和Window.Current.Activated的组合。我将在通过进一步测试确认后更新我的问题。@LanceMcCarthy我想知道您为什么决定激活并恢复事件?为什么不更改单个VisibilityChanged?有趣的是,我从VisibilityChanged和遇到了一系列问题(这导致了这篇文章),在经历了很多头痛之后,我不得不将MediaCapture对象移动到App类。因此在PC版本VisibilityChanged仍在管理该捕获页面,但手机仍处于激活状态。我可能很快会将其移回PC方法。感谢您的确认!