Manage Life Cycle and State in A C Tut 2
Manage Life Cycle and State in A C Tut 2
Summary
Next steps
Important APIs
LocalSettings
RoamingSettings
In this part of the C++ tutorial series, you update your "Hello, world" app to respond to
life cycle events, and save user and session data.
In Windows 8.1, you can launch several apps and switch between them without
worrying about slowing down the system or running down the battery. That's because
the system automatically suspends (and sometimes closes) apps that are running in the
background. A well-designed app can be suspended, closed, and restarted by the
system and still seem as though it was running the entire time.
This is the second tutorial in a series. Before you start this tutorial, read Hello
World in C++.
You can see the complete code for this tutorial in the Hello World (C++)sample
on Code Gallery.
When an app is running, it can be suspended when the user switches away from it or
when Windows enters a low power state. While your app is suspended, it continues to
reside in memory so that the user can quickly and reliably switch between suspended
apps, and resume them. When your app is suspended and then resumed, you don't
have to write any extra code to make it look as though it had been running the entire
time.
But Windows can also close a suspended app at any time to free up memory for other
apps or to save power. When your app is closed, it's unloaded from memory. When the
user starts it again, the system must activate it, and that might mean that the app data
and user data must be reloaded.
When the user closes an app by pressing Alt+F4 or by using the close gesture, the app
is suspended for 10 seconds and then is closed.
Windows notifies your app when it suspends it, but doesn't provide additional
notification when it closes the app. That means your app must handle the suspended
event and use it to save its state and release its exclusive resources and file handles
immediately.
To create a good user experience, you want your app to look like it never stopped
running. The app should retain any data the user entered, settings they changed, and
so on. That means you must save your app's state when it's suspended, in case
Windows closes it, so that you can restore its state later.
There are two types of data for you to manage in your app: app data and session data.
The next steps show how to update the app to save these types of data. What state do
you have to save? Right now, the only thing the user can change is his or her name
entry. The user can also choose the Say "Hello" button to generate a personalized
greeting.
2.
#include "Common\SuspensionManager.h"
3.
C++
HelloWorld::Common::SuspensionManager::RegisterFrame(rootFrame, "appFrame");
3.
).
4.
Find the TextChanged event in the event list. In the text box for the event, type
"NameInput_TextChanged" as the name of the function that handles
the TextChanged event.
5.
when the event occurs. In the event handler, you save the nameInput text
inroamingSettings.
C++
auto roamingSettings =
Windows::Storage::ApplicationData::Current->RoamingSettings;
roamingSettings->Values->Insert("userName", nameInput->Text);
if (roamingSettings->Values->HasKey("userName"))
{
nameInput->Text = roamingSettings->Values->Lookup("userName")>ToString();
}
6.
Press F5 to build and run the app. Your name is saved as you enter it in the text
box.
Session data is temporary data that is relevant to the users current session in your app.
A session ends when the user closes the app, reboots the computer, or logs off the
computer. In your app, the Text of the greetingOutput TextBlock is session data. You
restore it only if Windows suspends and closes the app. You have to save the navigation
state of the app Frame, so that the app can be restored to the same page is was on,
and so that the SuspensionManager knows which page to restore the state of. You also
have to save the state of the page itself. This is where you save the greetingOutputtext.
You use the SuspensionManager class to save session state in
the Application.Suspending event handler.
(For more info about the other ways you can save state, see Managing app
data and Working with state efficiently.)
The App.xaml.cpp file contains a handler for the Application.Suspending event. This
event handler gets called when Windows is about to suspend your app. This is your
opportunity to save the state of the app in case it gets closed. You use
the SuspensionManager class to simplify saving session state. It saves the navigation
state of the app, and gives you the opportunity to save the session state of the active
page.
To save the session state
1.
2.
C++
#include <ppltasks.h>
using namespace concurrency;
3.
Calling SaveAsync saves the navigation state of the Frame and then gives
your Page the opportunity to save its content in its SaveState method.
4.
To save the page state, in Solution Explorer, open MainPage.xaml.cpp and then
add this code to the SaveStatemethod:
C++
The SuspensionManager class serializes and saves the pageState dictionary to an XML
file. Data saved in pageState is saved only for this session. You save
the greetingOutput text here.
5.
Choose Build > Build solution to make sure the app builds with no errors.
That's all you have to do to save your app's state before your app is closed. Now you
can learn how to restore your app's state the next time the user starts it.
Earlier, you saw that the App.xaml.cpp file contains code that handles your app's
activation. There are many different ways to activate an app. Here we look at
the Launch activation and the OnLaunched method.
An app is launched whenever it wasn't running and the user activates it. When an app is
launched, Windows displays its splash screen.
In App.xaml.cpp, let's look at the code that handles app activation. The code defines an
override of the OnLaunchedmethod. The code in this method is executed only if the
activation is a Launch activation. (You can override other methods to handle other
kinds of activation, but we don't do it here. For more info, see Application lifecycle.)
First, the code declares a Frame and tries to assign the current window contents to it.
C++
If the window already contains a Frame, the app is already initialized and
so Frame initialization is skipped.
If the app isn't initialized, the code creates a Frame to host the app pages. You register
the Frame with theSuspensionManager. This is the code you added in Step 1.
Next, the code checks the previous execution state to see how the app was last closed.
When the previous execution state is Terminated, it means that the last time the app
ran, Windows successfully suspended it and then closed it. In that case, you have to
restore the app's state.
C++
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and
associate it with
// a SuspensionManager key
rootFrame = ref new Frame();
HelloWorld::Common::SuspensionManager::RegisterFrame(rootFrame,
"appFrame");
if (e->PreviousExecutionState ==
ApplicationExecutionState::Terminated)
{
// TODO: Restore the saved session state only when
appropriate, scheduling the
// final launch steps after the restore is complete
}
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate to
the first page,
// configuring the new page by passing required
information as a navigation
// parameter
if (!rootFrame->Navigate(TypeName(MainPage::typeid), e>Arguments))
{
throw ref new FailureException("Failed to
create initial page");
}
}
// Place the frame in the current Window
Window::Current->Content = rootFrame;
// Ensure the current window is active
Window::Current->Activate();
}
Next, the code checks whether the Frame contains any content. If the app is running,
or the navigation state was restored, the Frame already has content. Otherwise,
the Frame navigates to the first page in the app. In this case, it navigates to MainPage.
C++
if (rootFrame->Content == nullptr)
{
// When the navigation stack isn't restored navigate
to the first page,
// configuring the new page by passing required
information as a navigation
// parameter
if (!rootFrame->Navigate(TypeName(MainPage::typeid),
e->Arguments))
{
Now that you know what happens when the app is started, let's look at how to restore
the app state.
To restore the app's state
1.
if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
{
// TODO: Restore the saved session state only when
appropriate, scheduling the
// final launch steps after the restore is complete
HelloWorld::Common::SuspensionManager::RestoreAsync();
2.
First, check to see whether the pageState dictionary exists and has a key
named greetingOutputText. If the key exists, use it to restore
the greetingOutput text.
C++
b.
Next, load the user name. Because you want the user name data to persist
over multiple sessions, you store it in the RoamingSettings app data container.
Let's add some code to see whether the user name exists and, if it does, to display it.
C++
3.
4.
C++
5.
6.
7.
/// <summary>
/// Populates the page with content passed during navigation. Any saved
state is also
8.
/// provided when recreating a page from a prior session.
9.
/// </summary>
10.
/// <param name="navigationParameter">The parameter value passed to
11.
/// <see cref="Frame::Navigate(Type, Object)"/> when this page was
initially requested.
12.
13.
/// </param>
/// <param name="pageState">A map of state preserved by this page during
an earlier
14.
/// session. This will be null the first time a page is
visited.</param>
15.
void MainPage::LoadState(Object^ sender, Common::LoadStateEventArgs^ e)
16.
{
17.
(void) sender;
// Unused parameter
18.
// Restore values stored in session state.
19.
if( e->PageState != nullptr && e->PageState>HasKey("greetingOutputText"))
20.
{
21.
greetingOutput->Text = e->PageState>Lookup("greetingOutputText")->ToString();
22.
}
23.
24.
// Restore values stored in app data.
25.
auto roamingSettings =
26.
Windows::Storage::ApplicationData::Current>RoamingSettings;
27.
if (roamingSettings->Values->HasKey("userName"))
28.
{
29.
nameInput->Text = roamingSettings->Values->Lookup("userName")>ToString();
30.
}
31.
}
32.
Now you can build and run the app, and see how the session state is saved and
restored. So far, you've tested your app in Visual Studio by running it in debug mode,
and stopped it by selecting Debug > Stop Debugging. But doing this causes the app
to perform a normal shutdown, and the Suspending event doesn't occur. Fortunately,
you can use other functionality in Microsoft Visual Studio to simulate suspending,
closing, and restoring an app.
To simulate suspending, closing, and restoring an app
1.
2.
Enter your name in the input box and choose "Say "Hello"". The greeting is
displayed.
3.
In Visual Studio, open the drop-down menu next to the Suspend button on
the Debug Location toolbar.
The Debug Location toolbar appears by default while the debugger is running. If you
don't see it, choose View >Toolbars > Debug Location to show it.
4.
5.
Press F5 to run the app again. The app is restored to its previous state.
6.
Type a different name in the text box, and choose "Say "Hello"".
7.
In Visual Studio, close the app by selecting Debug > Stop Debugging.
8.
Summary
Congratulations, you're done with the second tutorial! It taught how to save app data
and session state in a Windows Store app.
Next steps
The next part of this tutorial series teaches how to use the design tools in Visual Studio
to create a more complex UI. SeeNavigation, layout, and views (C++)..