charles petzold application lifecycle and state management
TRANSCRIPT
![Page 1: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/1.jpg)
Charles Petzoldwww.charlespetzold.com
Application Lifecycle andState Management
![Page 2: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/2.jpg)
Agenda
• Launching and closing• Isolated storage• Activation and deactivation• Tombstoning• Page state and application state• Obscuration• Idle detection
![Page 3: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/3.jpg)
• Phones run one app at a time– Apps not in foreground are closed or deactivated– Either way, process is terminated (usually)
• PhoneApplicationService fires lifecycle events– Launching and Closing– Activated and Deactivated
• State is not maintained when app is closed or deactivated unless you take steps to maintain it– Except in certain situations (more later)
Application Lifecycle
![Page 4: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/4.jpg)
• Application is closed when:– Application's first page is displayed, and…– User presses the phone's Back button
• The only way to close an application!• Process is terminated; all state is lost
– One exception: if Back button is pressed quickly, WP7 may reconnect to still-running process
– But don't count on it
Launching and Closing
![Page 5: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/5.jpg)
Launching and Closing Events
// App.xaml<shell:PhoneApplicationService Launching="Application_Launching" Closing="Application_Closing" ... />
// App.xaml.csvoid Application_Launching(object sender, LaunchingEventArgs e){}
void Application_Closing(object sender, ClosingEventArgs e){}
![Page 6: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/6.jpg)
• Every Windows phone has a Back button• Page fires BackKeyPress events when the
Back button is pressed• From the UI Design and Interaction Guide
for Windows Phone 7:
Back Button
Developers should only implement Back Button behaviors that navigate back or dismiss context menus or modal dialog boxes. All other implementations are prohibited.
![Page 7: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/7.jpg)
Prompting Before Exiting
BackKeyPress += new EventHandler<CancelEventArgs>(OnBackKeyPress); . . .private void OnBackKeyPress(object sender, CancelEventArgs e){ MessageBoxResult result = MessageBox.Show("Are you sure?", "Confirm", MessageBoxButton.OKCancel); e.Cancel = !(result == MessageBoxResult.OK);}
![Page 8: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/8.jpg)
demoLaunching and Closing
![Page 9: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/9.jpg)
• System.IO.IsolatedStorage namespace contains classes that provide access to virtual file system– IsolatedStorageFile– IsolatedStorageException– IsolatedStorageSettings
• Stored in memory on the phone• Permanently deleted if app is uninstalled• Not subject to quotas
Isolated Storage
![Page 10: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/10.jpg)
• Provides methods for:– Opening and closing isolated storage stores
• Also known as "isostores"– Creating, opening, copying, enumerating,
moving, renaming, and deleting isolated storage files
– Creating, opening, enumerating, moving, renaming, and deleting isolated storage folders
• AvailableFreeSpace property provides information about free space
IsolatedStorageFile
![Page 11: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/11.jpg)
• IsolatedStorageFile method for accessing per-application stores
GetUserStoreForApplication
App 1Store
App 2Store
Marketplace
App 1 App 2
Phone
![Page 12: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/12.jpg)
Writing to Isolated Storage
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()){ using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("Settings.xml", FileMode.Create, store)) { using (StreamWriter writer = new StreamWriter(stream)) { // TODO: Write to stream with StreamWriter } }}
![Page 13: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/13.jpg)
Reading from Isolated Storage
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()){ if (store.FileExists("Settings.xml")) { using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("Settings.xml", FileMode.Open, store)) { using (StreamReader reader = new StreamReader(stream)) { // TODO: Read from stream with StreamReader } } }}
![Page 14: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/14.jpg)
Deleting an Isolated Storage Fileusing (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()){ if (store.FileExists("Settings.xml")) store.DeleteFile("Settings.xml");}
![Page 15: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/15.jpg)
• Dictionary stored in isolated storage– Application scope– Accessed through
IsolatedStorageSettings.ApplicationSettings property
• Simplifies task of storing user preferences and other simple settings– For example, language preferences
• Private to each application
Application Settings
![Page 16: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/16.jpg)
Using ApplicationSettings
// Write to the ApplicationSettings dictionaryIsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;settings["Culture"] = "fr-fr";
// Read from the ApplicationSettings dictionarystring culture;IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;if (settings.TryGetValue<string>("Culture", out culture)) HtmlPage.Window.Alert(culture);
![Page 17: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/17.jpg)
Determining Available Space
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()){ Int64 available = store.AvailableFreeSpace; ...}
![Page 18: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/18.jpg)
• Performance of CreateFile, OpenFile, and other methods degrades with large numbers of files
• Rule of thumb: Segregate files into folders, with no more than 128 files per folder– "How Many Files are Too Many Files?"
• http://appangles.com/blogs/mickn/wp7/?p=6• Block reads and writes are more performant
than lots of little reads and writes
Isolated Storage Performance
![Page 19: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/19.jpg)
Creating an Isolated Storage Folderusing (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()){ store.CreateDirectory("\XML Stuff");
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("\XML Stuff\Settings.xml", FileMode.Create, store)) { ... }}
![Page 20: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/20.jpg)
demoIsolated Storage
![Page 21: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/21.jpg)
• Application is deactivated when:– User presses the phone's Start button– App launches a launcher or chooser– Device time-out locks the screen
• Unless you specify otherwise• Deactivation usually means process is
terminated– Notable exception: When certain choosers such
as PhotoChooserTask are launched• Termination means all state is lost
Activation and Deactivation
![Page 22: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/22.jpg)
Activated and Deactivated Events// App.xaml<shell:PhoneApplicationService Activated="Application_Activated" Deactivated="Application_Deactivated" ... />
// App.xaml.csvoid Application_Activated(object sender, ActivatedEventArgs e){}
void Application_Deactivated(object sender, DeactivatedEventArgs e){}
![Page 23: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/23.jpg)
demoActivation and Deactivation
![Page 24: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/24.jpg)
• Occurs when app is deactivated and terminated
• To restore app to same state when reactivated, persist state in application state or page state– Or use isolated storage if volume of data exceeds
limits on application state and page state– Isolated storage is 30% to 50% slower
• Use page's OnNavigatedFrom and OnNavigatedTo methods to save and restore state
• App is allowed 10 seconds to tombstone data
Tombstoning
![Page 25: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/25.jpg)
• Data store for tombstoning global data– Limited to approx. 1.5 MB per app
• Dictionary accessed through PhoneApplicationService.State property
• Available between Activated and Deactivated events, inclusive
• Data must be serializable
Application State
![Page 26: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/26.jpg)
Saving Application State
void Application_Deactivated(object sender, DeactivatedEventArgs e){ PhoneApplicationService.Current.State["x1"] = x1; PhoneApplicationService.Current.State["y1"] = y1; PhoneApplicationService.Current.State["x2"] = x2; PhoneApplicationService.Current.State["y2"] = y2;}
![Page 27: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/27.jpg)
Restoring Application State
void Application_Activated(object sender, ActivatedEventArgs e){ if (PhoneApplicationService.Current.State.ContainsKey("x1")) x1 = (double)PhoneApplicationService.Current.State["x1"];
if (PhoneApplicationService.Current.State.ContainsKey("y1")) y1 = (double)PhoneApplicationService.Current.State["y1"];
if (PhoneApplicationService.Current.State.ContainsKey("x2")) x2 = (double)PhoneApplicationService.Current.State["x2"];
if (PhoneApplicationService.Current.State.ContainsKey("y2")) y2 = (double)PhoneApplicationService.Current.State["y2"];}
![Page 28: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/28.jpg)
• Data store for tombstoning per-page data– Limited to 2 MB per page and 4 MB per app
• Dictionary accessed through PhoneApplicationPage.State property
• Available between OnNavigatedTo and OnNavigatedFrom methods, inclusive
• Data must be serializable
Page State
![Page 29: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/29.jpg)
Saving Page State
protected override void OnNavigatedFrom(NavigationEventArgs e){ this.State["x1"] = x1; this.State["y1"] = y1; this.State["x2"] = x2; this.State["y2"] = y2;}
![Page 30: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/30.jpg)
Restoring Page State
protected override void OnNavigatedTo(NavigationEventArgs e){ if (this.State.ContainsKey("x1")) x1 = (double)this.State["x1"];
if (this.State.ContainsKey("y1")) y1 = (double)this.State["y1"];
if (this.State.ContainsKey("x2")) x2 = (double)this.State["x2"];
if (this.State.ContainsKey("y2")) y2 = (double)this.State["y2"];}
![Page 31: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/31.jpg)
demoTombstoning
![Page 32: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/32.jpg)
Tombstoning a ListBox Control
protected override void OnNavigatedFrom(NavigationEventArgs e){ // Save the ListBox control's SelectedIndex in page state this.State["Index"] = ListBoxControl.SelectedIndex;} protected override void OnNavigatedTo(NavigationEventArgs e){ // Restore the ListBox control's SelectedIndex if (this.State.ContainsKey("Index")) ListBoxControl.SelectedIndex = (int)this.State["Index"];}
![Page 33: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/33.jpg)
Tombstoning a Pivot Control
// This doesn't workprotected override void OnNavigatedFrom(NavigationEventArgs e){ // Save the Pivot control's SelectedIndex in page state this.State["Index"] = PivotControl.SelectedIndex;} protected override void OnNavigatedTo(NavigationEventArgs e){ // Restore the Pivot control's SelectedIndex if (this.State.ContainsKey("Index")) PivotControl.SelectedIndex = (int)this.State["Index"];}
![Page 34: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/34.jpg)
Tombstoning a Pivot Control, Cont.// This worksprotected override void OnNavigatedFrom(NavigationEventArgs e){ // Save the Pivot control's SelectedIndex in page state this.State["Index"] = PivotControl.SelectedIndex;} // Handler for Pivot.Loaded eventvoid OnPivotControlLoaded(object sender, RoutedEventArgs e){ // Restore the Pivot control's SelectedIndex if (this.State.ContainsKey("Index")) _index = (int)this.State["Index"];}
![Page 35: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/35.jpg)
Tombstoning a Panorama Control// This doesn't workprotected override void OnNavigatedFrom(NavigationEventArgs e){ // Save the Panorama control's SelectedIndex in page state this.State["Index"] = PanoramaControl.SelectedIndex;} protected override void OnNavigatedTo(NavigationEventArgs e){ // Restore the Panorama control's SelectedIndex if (this.State.ContainsKey("Index")) PanoramaControl.SelectedIndex = (int)this.State["Index"];}
![Page 36: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/36.jpg)
Tombstoning a Panorama, Cont.// This worksprotected override void OnNavigatedFrom(NavigationEventArgs e){ // Save the Panorama control's SelectedIndex in page state this.State["Index"] = PanoramaControl.SelectedIndex;} protected override void OnNavigatedTo(NavigationEventArgs e){ // Restore the Panorama control's SelectedIndex if (this.State.ContainsKey("Index")) PanoramaControl.DefaultItem = PanoramaControl.Items[(int)State["Index"]];}
![Page 37: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/37.jpg)
demoTombstoning Pivot Controls
![Page 38: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/38.jpg)
• Fired by PhoneApplicationFrame– Obscured – Shell comes to the foreground– Unobscured – App returns to the foreground
• Common causes:– Phone receives an incoming call– Screen times out and lock screen appears
• If app has disabled idle detection• Some apps must handle these events to
pass certification requirements
Obscured and Unobscured Events
![Page 39: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/39.jpg)
Handling Obscuration Events
(Application.Current as App).RootFrame.Obscured += OnObscured;(Application.Current as App).RootFrame.Unobscured += OnUnobscured; . . .private void OnObscured(object sender, ObscuredEventArgs e){ // Application is obscured by shell (possibly an incoming call) VibrateController.Default.Stop(); // Sample action}
private void OnUnobscured(object sender, EventArgs e){ // Application has returned to the foreground}
![Page 40: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/40.jpg)
• By default, apps are deactivated when screen locks
• Apps can continue running when screen locks by disabling ApplicationIdleDetectionMode– Primarily for apps that are slow to reactivate– Also for apps that need to run under lock (e.g.,
audio)– Obscured and Obscured events replace
Activated and Deactivated events• Apps can also disable
UserIdleDetectionMode to prevent screen from locking automatically
Idle Detection
![Page 41: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/41.jpg)
Disabling Application Idle Detection// Allow the app to run when screen is locked. Once disabled,// ApplicationIdleDetectionMode cannot be reenabled while the// app is running.
PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
![Page 42: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/42.jpg)
Disabling User Idle Detection
// Prevent screen from locking while this app runsPhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
![Page 43: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/43.jpg)
Detecting a Locked Screen
(Application.Current as App).RootFrame.Obscured += OnObscured;(Application.Current as App).RootFrame.Unobscured += OnUnobscured; . . .private void OnObscured(object sender, ObscuredEventArgs e){ if (e.IsLocked) { // Screen is locked }}
private void OnUnobscured(object sender, EventArgs e){ // Screen is no longer locked}
![Page 44: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/44.jpg)
demoRunning Under a Locked Screen
![Page 45: Charles Petzold Application Lifecycle and State Management](https://reader031.vdocument.in/reader031/viewer/2022032306/56649c765503460f94929d95/html5/thumbnails/45.jpg)
Charles Petzoldwww.charlespetzold.com
Questions?