MediaCapture 和窗口可见性已更改 [英] MediaCapture and Window VisibilityChanged

查看:26
本文介绍了MediaCapture 和窗口可见性已更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[问题]

在 Windows Phone 8.1 上,在用户离开应用程序和 OnSuspended 事件触发之间究竟发生了什么?我无法管理该跨度中的对象,尤其是 MediaCpture 对象.

On Windows Phone 8.1, what exactly happens in between the time when the user leaves the app and the OnSuspended event fires? I'm having trouble with the ability to manage objects in that span, in particular MediaCpture object.

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

To better explain the problem, here is the scenario:

  1. 用户在一个页面上,视频预览被泵送到 CaptureElement
  2. 用户点击开始"按钮
  3. 用户点击返回按钮并返回到 MediaCapture 损坏的页面

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

With WinRT there isn't an ObscuredEvent and OnNavigatingFrom doesn’t fire unless you’re going to another page in the same Frame. After some investigation, I've found that the only event that fires is Window.Current.VisibilityChanged

当页面处于 NavigatedTo 并在 OnNavigatedFrom 中解开时,我已经继续并钩住了它(参见下面的 ex2).在事件内部,我检查了指示应用程序是隐藏还是显示的参数,并相应地处理/初始化(参见下面的示例 1).

I've gone ahead and hook it when the page is NavigatedTo and unhooked in OnNavigatedFrom (see ex2 below). Inside the event, I check for parameter that tells if the app is hiding or showing and dispose/initialize accordingly(see ex.1 below).

[问题]

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

However, this only works with the debugger attached. If I do this without the debugger attached, it doesn't reinitialize and frequently crashes the camera and I have to literally reboot the device.

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

Code Example 1 (note: e.Visible == false is leaving the app and true when returning)

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(与事件挂钩)

Example 2 (hooking into the event)

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 参数.像这样:

Instead of using VisibilityChanged, hook into Window.Current.Activated on the page's constructor. With the debugger completely detached, the Activated event will provide the WindowActivationState parameter in the WindowActivatedEventArgs. Like this:

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 事件是否更合适.请注意,在这种情况下,您必须正确调试它 - 它在带有/不带有调试器的情况下运行时的行为几乎没有什么不同.

I'm not sure if it wouldn't be more suitable to use Suspending/Resuming events. Note only that in this case, you will have to debug it properly - it behaves little different while being run with/without debugger attached.

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

As for the code - hooking your event in OnNavigatedTo/OnNavigatedFrom is not a good idea - when the OS suspends the app and you are using SuspensionManager then OnNavigatedFrom will be called, but when you go back to your app (resume it), then OnNavigatedTo will not be called.

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

Using Window events may also work here, but why not subscribe it once, somewhere in constructor? - it's window-wide and hence in phone there is only one window, which stands for app, then subscribe once. In this case, you may add a line that recognizes the current page in window and if that page contains mediacapture then dispose (create similar). Then you can also dispose/initialize in navigation events in case user doesn't leave your app and just navigate.

这篇关于MediaCapture 和窗口可见性已更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆