處理應用程式預先啟動Handle app prelaunch

了解如何透過覆寫 OnLaunched 方法來處理 App 預先啟動。Learn how to handle app prelaunch by overriding the OnLaunched method.

簡介Introduction

當可用的系統資源允許時,會透過在背景主動啟動使用者最常使用的應用程式,來改善電腦裝置系列裝置上 UWP 應用程式的啟動效能。When available system resources allow, the startup performance of UWP apps on desktop device family devices is improved by proactively launching the user’s most frequently used apps in the background. 預先啟動的 App 在啟動不久後就會立即進入暫停狀態。A prelaunched app is put into the suspended state shortly after it is launched. 然後,當使用者叫用 App 時,App 會從暫停狀態切換到執行中狀態來繼續執行,這比 App 冷啟動快。Then, when the user invokes the app, the app is resumed by bringing it from the suspended state to the running state--which is faster than launching the app cold. 使用者所體驗到的就是 App 啟動非常快速。The user's experience is that the app simply launched very quickly.

在 Windows 10 之前,App 並未自動利用預先啟動。Prior to Windows 10, apps did not automatically take advantage of prelaunch. 在 Windows 10 版本 1511 中,通用 Windows 平台 (UWP) app 已成為預先啟動的候選項目。In Windows 10, version 1511, all Universal Windows Platform (UWP) apps were candidates for being prelaunched. 在 Windows 10 版本 1607 中,您必須透過呼叫 CoreApplication.EnablePrelaunch(true),才能加入預先啟動行為。In Windows 10, version 1607, you must opt-in to prelaunch behavior by calling CoreApplication.EnablePrelaunch(true). OnLaunched() 內靠近進行 if (e.PrelaunchActivated == false) 檢查的位置就是放置這個呼叫的好地方。A good place to put this call is within OnLaunched() near the location that the if (e.PrelaunchActivated == false) check is made.

是否會預先啟動 App,取決於系統資源。Whether an app is prelaunched depends on system resources. 如果系統感到資源壓力,就不會預先啟動應用程式。If the system is experiencing resource pressure, apps are not prelaunched.

某些類型的 App 可能需要變更其啟動行為,才能搭配預先啟動正常運作。Some types of apps may need to change their startup behavior to work well with prelaunch. 例如,在啟動時播放音樂的 App、假設使用者在場並在應用程式啟動時顯示精美視覺效果的遊戲、在啟動期間變更使用者線上可見度的訊息中心 App,皆可以識別 App 何時已預先啟動並可變更其啟動行為,如下列各節所述。For example, an app that plays music when its starts up, a game which assumes the user is present and displays elaborate visuals when the app starts up, a messaging app that changes the user's online visibility during startup, can identify when the app was prelaunched and can change their startup behavior as described in the sections below.

XAML 專案 (C#、VB、C++) 及 WinJS 的預設範本皆納入了 Visual Studio 2015 Update 3 中的預先啟動。The default templates for XAML Projects (C#, VB, C++) and WinJS accommodate prelaunch in Visual Studio 2015 Update 3.

預先啟動與 App 週期Prelaunch and the app lifecycle

應用程式在預先啟動之後,將會進入暫停狀態。After an app is prelaunched, it will enter the suspended state. (請參閱處理 app 暫停)。(see Handle app suspend).

偵測和處理預先啟動Detect and handle prelaunch

App 在啟動期間會收到 LaunchActivatedEventArgs.PrelaunchActivated 旗標。Apps receive the LaunchActivatedEventArgs.PrelaunchActivated flag during activation. 使用此旗標來執行程式碼,該程式碼只應在使用者明確啟動應用程式時執行,如下列 >onlaunched修改所示。Use this flag to run code that should only run when the user explicitly launches the app, as shown in the following modification to 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>
/// Encapsulates the call to CoreApplication.EnablePrelaunch() so that the JIT
/// won't encounter that call (and prevent the app from running when it doesn't
/// find it), unless this method gets called. This method should only
/// be called when the caller determines that we are running on a system that
/// supports CoreApplication.EnablePrelaunch().
/// </summary>
private void TryEnablePrelaunch()
{
    Windows.ApplicationModel.Core.CoreApplication.EnablePrelaunch(true);
}

請注意 TryEnablePrelaunch() 上述函數。Note the TryEnablePrelaunch() function, above. 將呼叫帶出至此函式的原因 CoreApplication.EnablePrelaunch() 是,當呼叫方法時,JIT (即時編譯) 將會嘗試編譯整個方法。The reason the call to CoreApplication.EnablePrelaunch() is factored out into this function is because when a method is called, the JIT (just in time compilation) will attempt to compile the entire method. 如果您的應用程式是在不支援的 Windows 10 版本上執行 CoreApplication.EnablePrelaunch() ,則 JIT 將會失敗。If your app is running on a version of Windows 10 that doesn't support CoreApplication.EnablePrelaunch(), then the JIT will fail. 藉由將呼叫的方法,只會在應用程式判斷平臺所支援的情況 CoreApplication.EnablePrelaunch() 下呼叫,我們就可以避免這個問題。By factoring the call into a method that is only called when the app determines that the platform supports CoreApplication.EnablePrelaunch(), we avoid that problem.

上述範例中也有一些程式碼,如果您的應用程式在 Windows 10 1511 版上執行時需要退出預先啟動,您可以取消批註。There is also code in the example above that you can uncomment if your app needs to opt-out of prelaunch when running on Windows 10, version 1511. 在1511版中,所有 UWP 應用程式都會自動進入預先啟動,這可能不適合您的應用程式。In version 1511, all UWP apps were automatically opted into prelaunch, which may not be appropriate for your app.

使用 VisibilityChanged 事件Use the VisibilityChanged event

使用者看不到預先啟動所啟動的應用程式。Apps activated by prelaunch are not visible to the user. 當使用者切換到它們時,才會顯示。They become visible when the user switches to them. 您可能會想要將某些操作延遲到應用程式主視窗顯示之後才進行。You may want to delay certain operations until your app's main window becomes visible. 例如,如果您的 App 會從摘要中顯示最新動向項目清單,您可以在 VisibilityChanged 事件期間更新該清單,而不用使用預先啟動 App 時所建置的清單,因為等到使用者啟用 App 時該清單可能已過時。For example, if your app displays a list of what's new items from a feed, you could update the list during the VisibilityChanged event rather than use the list that was built when the app was prelaunched because it may become stale by the time the user activates the app. 下列程式碼會處理 MainPageVisibilityChanged 事件:The following code handles the VisibilityChanged event for MainPage:

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 games guidance

DirectX 遊戲通常不應該啟用預先啟動,因為許多 DirectX 遊戲是在系統能夠偵測到預先啟動之前就進行其初始化。DirectX games should generally not enable prelaunch because many DirectX games do their initialization before prelaunch can be detected. 從 Windows 1607 (年度版) 開始,預設將不會預先啟用您的遊戲。Starting with Windows 1607, Anniversary edition, your game will not be prelaunched by default. 如果您確實希望您的遊戲利用預先啟動,請呼叫 CoreApplication.EnablePrelaunch(true)If you do want your game to take advantage of prelaunch, call CoreApplication.EnablePrelaunch(true).

如果您的遊戲是以舊版 Windows 10 為目標,則您可以處理預先啟動條件來結束應用程式:If your game targets an earlier version of Windows 10, you can handle the prelaunch condition to exit the application:

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;
        }
    }
}

WinJS 應用程式指導方針WinJS app guidance

如果您的 WinJS 應用程式是以舊版 Windows 10 為目標,則您可以在 onactivated 處理常式中處理預先啟動條件:If your WinJS app targets an earlier version of Windows 10, you can handle the prelaunch condition in your onactivated handler:

    app.onactivated = function (args) {
        if (!args.detail.prelaunchActivated) {
            // 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.
        }
    }

一般指導方針General Guidance

  • App 不應該在預先啟動期間執行長時間執行的操作,因為如果無法快速暫停 App,App 就會終止。Apps should not perform long running operations during prelaunch because the app will terminate if it can't be suspended quickly.
  • 當預先啟動應用程式時,應用程式不應初始化 Application.OnLaunched 的音訊播放,因為將會看不到應用程式,所以無法知道為什麼會播放音訊。Apps should not initiate audio playback from Application.OnLaunched when the app is prelaunched because the app won't be visible and it won't be apparent why there is audio playing.
  • 假設使用者可以看見應用程式,或假設應用程式是由使用者明確啟動,那麼應用程式在啟動期間不應該執行任何操作。Apps should not perform any operations during launch which assume that the app is visible to the user, or assume that the app was explicitly launched by the user. 由於應用程式現在不需明確的使用者動作即可在背景中啟動,因此開發人員應該考量隱私權、使用者體驗及可能的效能影響。Because an app can now be launched in the background without explicit user action, developers should consider the privacy, user experience and performance implications.
    • 隱私權考量舉例:社交應用程式應該在何時將使用者狀態變更為線上。An example privacy consideration is when a social app should change the user state to online. 它應該等到使用者切換到應用程式,而不是在預先啟動應用程式時變更狀態。It should wait until the user switches to the app instead of changing the status when the app is prelaunched.
    • 使用者體驗考量舉例:如果您的應用程式 (例如遊戲) 會在啟動時顯示一個開場片段,則您可以將開場片段延遲到使用者切換到該應用程式之後才顯示。An example user experience consideration is that if you have an app, such as a game, that displays an introductory sequence when it is launched, you might delay the introductory sequence until the user switches to the app.
    • 效能影響舉例:您可以等到使用者切換到 App 才擷取當前的天氣資訊,而不是在預先啟動 App 時就載入該資訊,然後在 App 變成可見時,需要再次載入該資訊以確保該資訊是當前的。An example performance implication is that you might wait until the user switches to the app to retrieve the current weather information instead of loading it when the app is prelaunched and then need to load it again when the app becomes visible to ensure that the information is current.
  • 如果您的 App 會在啟動時清除其動態磚,請將此操作延遲到可見度變更事件發生之後才進行。If your app clears its Live Tile when launched, defer doing this until the visibility changed event.
  • 您 App 的遙測應該要能區分一般磚啟用和預先啟動啟用,以便讓您能夠在問題發生時縮小狀況範圍。Telemetry for your app should distinguish between normal tile activations and prelaunch activations to make it easier to narrow down the scenario if problems occur.
  • 如果您有 Microsoft Visual Studio 2015 Update 1 和 Windows 10 版本 1511,您可以在 Visual Studio 2015 中選擇 [偵錯] > [其他偵錯目標] > [偵錯 Windows 通用應用程式預先啟動],來模擬 App 的預先啟動。If you have Microsoft Visual Studio 2015 Update 1, and Windows 10, Version 1511, you can simulate prelaunch for App your app in Visual Studio 2015 by choosing Debug > Other Debug Targets > Debug Windows Universal App PreLaunch.