I found that the application life cycle of Windows Phone applications is not so simple as I expected. Here is a pseudo code to fulfill the requirements. See Execution Model for Windows Phone (http://msdn.microsoft.com/en-us/library/ff769557%28v=vs.92%29.aspx) for details.
private void Application_Launching(object sender, LaunchingEventArgs e)
{
// Launching to Running state.
// If application persistent state is available, it should be restored.
// However, it should not be done here to avoid consuming too much time
// on launching.
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
if (e.IsApplicationInstancePreserved)
{
// Activated from Dormant state.
}
else
{
// Activated from Tombstoned state.
// Restore the application transient state which was saved
// during the last call of Application_Deactivated() method.
var state = PhoneApplicationService.Current.State;
RestoreApplicationTransientState(state);
}
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
// Deactivated to Dormant state.
// Save the application transient state which may be used later
// by Application_Activated() method in case this application is
// relaunched from Tombstoned state.
var state = PhoneApplicationService.Current.State;
SaveApplicationTransientState(state);
// Save the application persistent state to isolated storage
// because this application may be terminated without being
// activated, and in such a case, Application_Closing() is
// not called.
SaveApplicationPersistentState();
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
// Save the application persistent state to isolated storage
// to reuse it later on next invocation.
SaveApplicationPersistentState();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// If this page instance is new.
//
// The variable _isNewPageInstance here is an instance variable
// and initialized to true in this page's constructor.
if (_isNewPageInstance)
{
if (0 < State.Count)
{
// Activated from Tombstoned state.
// Use the page state data to build up this page.
// The data was saved during the last call of
// OnNavigatedFrom() method which was executed
// when this application entered Dormant state.
RestorePageState(State);
}
else
{
// Normal forward page navigation. Build up this page
// from scratch.
InitializePageState(State);
}
_isNewPageInstance = false;
}
else
{
// Activated from Dormant state, or
// normal page backward navigation.
// There is nothing to do because the page state remains
// intact in memory.
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
// Normal backward page navigation.
// No need to save the page state because this page
// instance is about to be discarded.
}
else
{
// Save the page state to reuse it later when this
// application is activated from Tombstoned state.
SavePageState(State);
}
}
Windows Phoneアプリケーションのライフサイクル
Windows Phone アプリケーションのライフサイクルは、期待していたほど単純なものではなかった。要求事項を満たすための擬似コードは下記の通り。詳細は Execution Model for Windows Phone (http://msdn.microsoft.com/en-us/library/ff769557%28v=vs.92%29.aspx) を参照のこと。
private void Application_Launching(object sender, LaunchingEventArgs e)
{
// Launching to Running state.
// もしもアプリケーションの永続状態が利用可能であれば、復元する。
// ただし、起動時に多くの時間を消費しないように、復元はここでは
// おこなわない。
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
if (e.IsApplicationInstancePreserved)
{
// Activated from Dormant state.
}
else
{
// Activated from Tombstoned state.
// 最後の Application_Deactivated() メソッドの呼び出しの際に
// 保存されたアプリケーションの一時状態を復元する。
var state = PhoneApplicationService.Current.State;
RestoreApplicationTransientState(state);
}
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
// Deactivated to Dormant state.
// このアプリケーションが Tombstoned 状態から再起動された場合に
// Application_Activated() メソッドで使用することになる、アプリ
// ケーションの一時状態を保存する。
var state = PhoneApplicationService.Current.State;
SaveApplicationTransientState(state);
// Activate されることなくアプリケーションが終了させられることも
// ありうるので(そのケースでは Application_Closing() は呼ばれない)、
// アプリケーションの永続状態を isolated storage に保存しておく。
SaveApplicationPersistentState();
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
// 次回の起動時に再利用できるよう、アプリケーションの永続状態を
// isolated storage に保存する。
SaveApplicationPersistentState();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// このページインスタンスが新しい場合
//
// 変数 _isNewPageInstance はインスタンス変数で、このページの
// コンストラクタで true に初期化される。
if (_isNewPageInstance)
{
if (0 < State.Count)
{
// Activated from Tombstoned state.
// ページの状態データを使ってこのページを構築する。
// データは、このアプリケーションが Dormant state に
// 移行するときに実行された OnNavigatedFrom() メソッド
// の呼び出し中に保存されたもの。
RestorePageState(State);
}
else
{
// 通常の前方ページ遷移。このページを一から構築する。
InitializePageState(State);
}
_isNewPageInstance = false;
}
else
{
// Activated from Dormant state, もしくは通常の後方ページ遷移。
// ページの状態はメモリ上にそのまま残っているので、ここでは
// 特にすることはない。
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
// 通常の後方ページ遷移
// このページインスタンスは破棄されようとしているところなので、
// ページの状態を保存する必要はない。
}
else
{
// 後でアプリケーションが Tombstoned 状態から復帰したときに
// 再利用するため、ページの状態を保存しておく。
SavePageState(State);
}
}