处理应用预启动

了解如何通过重写 OnLaunched 方法并调用 CoreApplication.EnablePrelaunch 来处理应用预启动。

介绍

当允许使用可用的系统资源时,可通过在后台主动启动用户的最常用应用,提升桌面设备系列设备上的 UWP 应用的启动性能。 启动后不久,预启动的应用将进入暂停状态。 然后,当用户调用应用时,通过将应用从挂起状态引入运行状态来恢复应用,这比启动应用冷的速度要快。 用户体验是应用只是很快启动。

在 Windows 10 之前,应用不会自动利用预启动。 在 Windows 10 版本 1511 中,所有通用 Windows 平台(UWP)应用都是预启动的候选应用。 在 Windows 10 版本 1607 中,必须通过调用 CoreApplication.EnablePrelaunch 并传递 true来选择预启动行为。 将此呼叫放在 OnLaunched,靠近检查的位置if (e.PrelaunchActivated == false)

是否预启动应用取决于系统资源。 如果系统遇到资源压力,则不会预启动应用。

某些类型的应用可能需要更改其启动行为才能很好地使用预启动。 例如,启动时播放音乐的应用;一个游戏,假定用户存在,并在应用启动时显示精心制作的视觉对象;一个消息应用,用于在启动期间更改用户的联机可见性 -- 所有这些应用都可以识别何时预启动应用,并且可以更改其启动行为,如以下各节中所述。

XAML 项目(C#、VB、C++)的默认模板适合预启动。

预启动和应用生命周期

应用预启动后,它将进入暂停状态。 (请参阅 处理应用挂起)。

检测和处理预启动

应用在激活期间接收 LaunchActivatedEventArgs.PrelaunchActivated 标志。 使用此标志运行应仅在用户显式启动应用(如以下显示的对 Application.OnLaunched 的修改)时运行的代码。

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    // CoreApplication.EnablePrelaunch was introduced in Windows 10 version 1607
    bool canEnablePrelaunch = Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch");

    // NOTE: Only enable this code if you are targeting a version of Windows 10 prior to version 1607,
    // and you want to opt out of prelaunch.
    // In Windows 10 version 1511, all UWP apps were candidates for prelaunch.
    // Starting in Windows 10 version 1607, the app must opt in to be prelaunched.
    //if ( !canEnablePrelaunch && e.PrelaunchActivated == true)
    //{
    //    return;
    //}

    Frame rootFrame = Window.Current.Content as Frame;

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();

        rootFrame.NavigationFailed += OnNavigationFailed;

        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: Load state from previously suspended application
        }

        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }

    if (e.PrelaunchActivated == false)
    {
        // On Windows 10 version 1607 or later, this code signals that this app wants to participate in prelaunch
        if (canEnablePrelaunch)
        {
            TryEnablePrelaunch();
        }

        // TODO: This is not a prelaunch activation. Perform operations which
        // assume that the user explicitly launched the app such as updating
        // the online presence of the user on a social network, updating a
        // what's new feed, etc.

        if (rootFrame.Content == null)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }
        // Ensure the current window is active
        Window.Current.Activate();
    }
}

/// <summary>
/// This method should be called only when the caller
/// determines that we're running on a system that
/// supports CoreApplication.EnablePrelaunch.
/// </summary>
private void TryEnablePrelaunch()
{
    Windows.ApplicationModel.Core.CoreApplication.EnablePrelaunch(true);
}

重要

上面的代码示例中的 TryEnablePrelaunch 方法调用 CoreApplication.EnablePrelaunch仅当应用在支持 CoreApplication.EnablePrelaunch 的 Windows 版本上运行时,才调用 TryEnablePrelaunch。 通常,如果有疑问,则只有在确定代码正在运行的平台支持 Windows API 后,才应使用 Windows API。 可以通过 ApiInformation 类执行此操作,如上面的代码示例所示。

上面的示例中还存在代码,如果你的应用需要在 Windows 10 版本 1511 上运行时选择退出预启动,则可以取消注释。 在版本 1511 中,所有 UWP 应用都自动选择预启动,这可能不适合你的应用。

使用 VisibilityChanged 事件

预启动激活的应用对用户不可见。 当用户切换到它们时,它们变得可见。 你可能希望延迟某些操作,直到应用的主窗口可见。 例如,如果你的应用显示源中新增项的列表,则可以在 VisibilityChanged 事件期间更新列表,而不是使用在预启动应用时生成的列表,因为它在用户激活应用时可能会过时。 以下代码处理 MainPageVisibilityChanged 事件:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        Window.Current.VisibilityChanged += WindowVisibilityChangedEventHandler;
    }

    void WindowVisibilityChangedEventHandler(System.Object sender, Windows.UI.Core.VisibilityChangedEventArgs e)
    {
        // Perform operations that should take place when the application becomes visible rather than
        // when it is prelaunched, such as building a what's new feed
    }
}

DirectX 游戏指南

DirectX 游戏通常不应启用预启动,因为许多 DirectX 游戏在检测到预启动之前会执行其初始化。 从 Windows 1607 周年版开始,默认情况下不会预启动你的游戏。 如果确实希望游戏利用预启动,请调用 CoreApplication.EnablePrelaunch(true)。

如果你的游戏面向早期版本的 Windows 10,则可以处理预启动条件以退出应用程序:

void ViewProvider::OnActivated(CoreApplicationView const& /* appView */, Windows::ApplicationModel::Activation::IActivatedEventArgs const& args)
{
    if (args.Kind() == Windows::ApplicationModel::Activation::ActivationKind::Launch)
    {
        auto launchArgs{ args.as<Windows::ApplicationModel::Activation::LaunchActivatedEventArgs>()};
        if (launchArgs.PrelaunchActivated())
        {
            // Opt-out of Prelaunch.
            CoreApplication::Exit();
        }
    }
}

void ViewProvider::Initialize(CoreApplicationView const & appView)
{
    appView.Activated({ this, &App::OnActivated });
}
void ViewProvider::OnActivated(CoreApplicationView^ appView,IActivatedEventArgs^ args)
{
    if (args->Kind == ActivationKind::Launch)
    {
        auto launchArgs = static_cast<LaunchActivatedEventArgs^>(args);
        if (launchArgs->PrelaunchActivated)
        {
            // Opt-out of Prelaunch
            CoreApplication::Exit();
            return;
        }
    }
}

通用指南

  • 应用在预启动期间不应执行长时间运行的操作,因为如果应用无法快速暂停,应用将终止。
  • 当预启动应用时,应用不应从 Application.OnLaunched 启动音频播放,因为该应用不可见,并且不会明显为什么有音频播放。
  • 应用不应在启动期间执行任何操作,该操作假定该应用对用户可见,或者假定该应用是由用户显式启动的。 由于应用现在可以在后台启动,而无需显式用户操作,因此开发人员应考虑隐私、用户体验和性能影响。
    • 例如,隐私注意事项是社交应用应将用户状态更改为联机状态。 它应等到用户切换到应用,而不是在预启动应用时更改状态。
    • 一个示例用户体验注意事项是,如果你有一个应用(如游戏)在启动时显示介绍性序列,你可能会延迟介绍性序列,直到用户切换到应用。
    • 例如,性能影响是,你可能等到用户切换到应用以检索当前天气信息,而不是在预启动应用时加载它,然后在应用变为可见时再次加载它,以确保信息是最新的。
  • 如果应用在启动时清除其动态磁贴,请延迟执行此操作,直到可见性更改事件。
  • 应用的遥测应区分普通磁贴激活和预启动激活,以便在出现问题时更轻松地缩小方案范围。
  • 如果已Microsoft Visual Studio 2015 Update 1 和 Windows 10 版本 1511,则可以通过选择“调试其他调试目标>调试>Windows 通用应用预启动”,在 Visual Studio 2015 中模拟应用的预启动。