MediaCapture 和 Window VisibilityChanged

MediaCapture and Window VisibilityChanged

[问题]

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

为了更好地解释问题,这里是场景:

  1. 用户所在的页面上有视频预览被推送到 CaptureElement
  2. 用户点击“开始”按钮
  3. 用户点击“后退”按钮 returns 到 MediaCapture 损坏的页面

对于 WinRT,没有 ObscuredEvent 并且 OnNavigatingFrom 不会触发,除非您要转到同一页面中的另一个页面框架。经过一些调查,我发现唯一触发的事件是 Window.Current.VisibilityChanged

我已经继续并在页面 NavigatedTo 中挂钩它并在 OnNavigatedFrom 中取消挂钩(参见下面的 ex2)。在该事件中,我检查指示应用程序是隐藏还是显示的参数,并相应地 dispose/initialize(参见下面的示例 1)。

[问题]

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

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

async void Current_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
{
     if (!e.Visible) //means leaving the app
     {
         await DisposeAll(); //cleans the MediaCapture and CaptureElement
     }
     else
     {
         if(mediaCaptureManager != null) await DisposeAll();

         await Initialization(); //set up camera again
     }
}

示例 2(连接到事件中)

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    Window.Current.VisibilityChanged += Current_VisibilityChanged;

    this.navigationHelper.OnNavigatedTo(e);
}

protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
    Window.Current.VisibilityChanged -= Current_VisibilityChanged;

    this.navigationHelper.OnNavigatedFrom(e);
}

[更新:决议]

不使用 VisibilityChanged,而是挂接到页面构造函数中的 Window.Current.Activated。在调试器完全分离的情况下,Activated 事件将在 WindowActivatedEventArgs 中提供 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
    }
}

我不确定使用 Suspending/Resuming 事件是否更合适。请注意,在这种情况下,您必须正确调试它 - 它 behaves little different while being run with/without debugger attached.

至于代码 - 在 OnNavigatedTo/OnNavigatedFrom 挂钩你的事件不是一个好主意 - 当 OS 暂停应用程序并且你正在使用 SuspensionManager 然后 OnNavigatedFrom 将被调用,但是当您返回您的应用程序(恢复它)时,然后 OnNavigatedTo 不会被调用。

使用Window事件也可以在这里工作,但为什么不在构造函数的某个地方订阅一次呢? - 它是 window-wide,因此在 phone 中只有一个 window,它代表应用程序,然后订阅一次。在这种情况下,您可以添加一行来识别 window 中的当前页面,如果该页面包含 mediacapture 然后处理(创建类似的)。然后,您还可以 dispose/initialize 在导航事件中,以防用户不离开您的应用而只是导航。

在 中查看我的回答。我相信将 Window.VisibilityChanged 与 Page\UserControl Loaded\Unloaded 处理程序结合使用应该可以解决您的问题。

使用 Window.Activated 不如 Window.VisibilityChanged 理想,因为 Activated 与可见性和焦点相关,而 VisibilityChanged 仅与可见性有关。对于显示具有焦点的预览不适用。由于 Windows Windows Phone 上的商店应用只能有一个 Window 显示使用两者都没有区别但是如果您的应用变得通用并且运行在 Windows 8+ Modern shell(可以通过 Snap window 功能显示多个 Store 应用)或 Windows 10 desktop(可以支持同时显示多个 Store 应用)当用户从您的应用更改焦点但您的应用仍在显示时,不想停止预览。