Windows Phone 8.1 - Application lifecycle 概念
Windows Phone 8.1 提供新 App 的類型:Windows Runtime App (XAML App),這與 Silverlight Application 有所不同,
它與 Windows Store App 撰寫方式相近,但因為我自己沒有寫過 Windows Store App,因此,藉由該篇針對新的 Windows
Runtime App 來加以了解。
Windows Runtime App 與過去 Silverlight Windows Phone App 在 Application Lifecycle 有很大的差別。
以 Silverlight Windows Phone App 可參考<Windows Phone 7 - 簡介新運作模式 – Dormant>。
那麼 Windows Runtime App 在 Lifecycle 根據<Application lifecycle (Windows Runtime apps)>所繪製的說明如下:
分成幾個 execution state:
a. App 第一次被開啟後,先由 Not running -> Activated -> Running;
=>第一次開啟:剛安裝、程式被完整關閉、重新開機;
b. 用戶按了 Start 鍵或是進入了其他 App ,狀態由 Running -> Suspending -> Suspended;
c. 用戶再開啟該 App 時,狀態將由 Suspended -> Resuming -> Running;
=>再開啟:從任務管理器返回、點擊 Tile 進入;
d. 如果在 Suspended 遇到系統記憶體不足時,App 將有可能會被刪除,變成:Suspended -> Not running;
=>但要注意狀態從 Suspended -> Not running 是不會收到任何事件通知的;
以上四個狀態與運作邏輯與與過去 Tombstone 不一樣的,並且把 activated 與 deactivate 變成由 Suspended 來取代。
App 退到背景時只是被暫停,但仍可藉由其他方式喚醒繼續操作,例如:File Picker、其他程式觸發、返回程式…等。
App 會被停止來自二個時機:(1) 由系統關閉了 App;(2) 由用戶自己將 App 從記憶體中去掉;
因此,以下將針對 ApplicationExecutionState enumeration 來加以說明可取得幾種 App 的狀態;
用於指示App執行的狀態。如以下列舉:
Member | Value | Description |
NotRunning | notRunning | 0 | The app is not running. |
Running | running | 1 | The app is running. |
Suspended | suspended | 2 | The app is suspended. |
Terminated | terminated | 3 | The app was terminated after being suspended. |
ClosedByUser | closedbyuser | 4 | The app was closed by the user. |
該列舉值會搭配「PreviousExecutionState」來使用,加以識別上次一個離開程式或目前狀態,針對不同的狀態讓 App 需要有對應的處理,
讓用戶是有感的,以免他誤以為 App 無回應將它關閉。
State | When this state is seen | What your app should do |
NotRunning |
當用戶第一次啟動該 App,啟動的類型有: a. 從 Store 剛安裝好 App; b. 從 Task Manager 將該 App 給強制停止 (end task); c. 手機重新啟動; d. App 被註消與重新啟動; e. 程式 Crash; |
呈現初始化 UI 與完成初始化任務。 |
Running | App 被經由 Secondary tile 或 activation contracts and extensions 的其中一種而啟動。 | 針對啟動事件產生一個回應。 |
Suspended | 當 App 暫停時被經由 Secondary tile 或 activation contracts and extensions 的其中一種而啟動。 | 針對啟動事件產生一個回應。 |
Terminated |
當系統執行發現記憶體或資源不足時,將自動結束 Suspend 的 App。 如果 App 在這個狀況下被結束,將會收到這個狀態。 |
建議在 App 進入 Suspend 時就將需保存的資料先保存好。 當下一次用戶開啟 App 時,即可以還原上次的資料。 |
ClosedByUser |
用戶藉由關閉手勢或按 Alt + F4 鍵來關閉 App。 下次一次開始需要等待需要超過 10 秒更長的時間。 |
在 Win 8 時,遇到這個狀態 App 則需要初始化畫面與基本任務。 在 Win 8.1 時,將依賴 Suspend 時將資料保存好,等到下一次用戶開啟 App 時將加以還原,而不是整個重新來過。 如果 App 常依賴 CloseByUser 的行為來識別,可搭配設定最後一個 window 的 TerminateAppOnFinalViewClose 屬性來關閉程式。 |
[補充]
App 被關閉可能來自幾種原因,可搭配在 OnActivated() 事件中的參數的 PreviousExecutionState 屬性,了解 App 的上一個狀態為何來處理
該怎麼呈現畫面才能比較符合用戶的期待:
Reason of termination | Value of PreviousExecutionState property | Action to take |
Terminated by the system (for example, because of resource constraints) |
Terminated | Restore session data |
Closed by the user | ClosedByUser | Start with default data |
Unexpectedly terminated, or app has not run since the user’s session started | NotRunning | Start with default data |
需注意,如果重新進入 App 時發現 PreviousExecutionState 是 Running 或 Suspend 時,代表您的 App 仍存在記憶體可以不用擔心還原資料的問題。
以下針對 App 在啟動、暫停等狀態加以說明發生的情境與可以搭配實作的邏輯:
〉App Launch:
當 App 前一個狀態是 Not Running,重新啟動 App 時將改變狀態為:Activated,系統將會呈現 App 的 splash screen(Adding a splash screen)。
當 splash screen 呈現時 App 將可以執行定義在 App.xaml.cs 中的事件、資料的載入等邏輯,當然你也可自訂一個延伸的 splash screen 來完成需要邏輯。
因為由系統呈現 splash screen 到進入 App 的第一個 Page 是有時間限制的,所以您的 App 是需要網路能力來同步或下載資料時,建議可以再拉一個 Page,
讓 App 呈現完 splash screen 進入該 Page 來完成整個邏輯。當這些都完成後,狀態變成為: Running。
詳細可參考<Extended Splash Screen documentation>與<Splash screen sample>。
〉App activation:
App 被啟動可能來自二種模式:(1) 用戶開啟該 App;(2) 用戶利用其他 contracts 或 extensions 來開啟;如果 App 希望處理這些 contracts 或 extensions,
需要先註冊來接收 「Activated | activated」的事件。然而實作的 activation event handler 需要去測試為什麼該 App 會被啟動或是本身已正在執行中。
可藉由下方提供的 activation type 來了解:
「The activated event arguments include a PreviousExecutionState property that tells you which state your app was in before it was activated.」
透過 PreviousExecutionState 屬性來判斷 App 的上一次離開前的狀態為何。例如:
識別上一個狀態為 Terminated,代表程式被系統關閉了所以要重新回覆離開前的資料與畫面。
其他可能影響 App 啟動的條件有:
對於 Windows 8.1 與 Windows Phone 8.1 也有更多的支援:
〉App suspend:
當 App 被退到 background 時,系統會預先等待幾秒中預防用戶又直接回到 App,如果用戶超過時限該 App 才會進入 Suspend。
而 Suspending handler 需要保存操作的資料、狀態、釋放資源與占用的檔案…等。可搭配 Application Model 來保存、還原資料。
建議您使用應用程式資料 API 進行,因為使用它們可以確保在應用程式進入 Suspended 狀態之前完成工作。
通常保存資料、狀態、釋放資源與占用的檔案,這些事件一般要在 1 秒內完成,需要更長的時間需要先請求延遲。
如果系統發現該 App 在 Windows 下從 suspending event 後超過 5 秒沒有回應,而 Windows Phone 下是超過 1~10 秒,系統將會
識別該 App 已經無法回應而將它停止。
通常系統會多留一些記憶體來存放進入 Suspend 的 App,支援使用者可在暫存的應用程式之間快速且可靠的切換,但如果真的系統
發現記憶體不足時則會終止這些已經被暫停的程式。要注意此時被終止的 App 並不會收到任何事件的通知,因此,建議 App 在補捉到
Suspend 事件時就該將資料保存完畢,讓 App 在重新開啟時可以判斷它是終止後又再度啟用時,則載入在暫停期間所儲存的應用程式資料。
詳細可參考<Guidelines for app suspend and resume>。
如果您的 App 希望可以在進入背景後還可以處理其他邏輯與事件,需要額外實作支援背景的任務。
詳細可參考:<快速入門:在 Windows 執行階段應用程式中新增音訊>與<快速入門:下載檔案>。
〉App visibility:
當用戶從目前的 App 到另一個 App 時,你的 App 將不再可見(進入背景)但仍然在處理狀態,大約在 10 秒後才會觸發 Suspend 的事件。
需注意,如果在 10 秒內用戶又切換回到你的 App,則 App 仍然是在 Running 的狀態。
當 App 的 visibility 改變時並不會觸發 activation event,因為 App 仍然正在運作。可註冊 VisibilityChanged | msvisibilitychange event
來處理一些邏輯,但千萬不要假設這些事件都在一個特定的順序。
〉App resume:
一個 suspend app 被重新啟動可能來自用戶切換回來或是其他事件。
當進入 Resuming 事件時可搭配 ApplicationExecutionState 得知上一個狀態。
需注意以下幾個狀態的返回對於資料還原的影響:
a. App 從 Suspended 狀態進入 Running,不會有任何 application data 遺失因為它被儲存在 memory 中;
=>因此大部分的 App 不太需要在 Resuming 事件做什麼邏輯。
b. 如果您的 App 內容是來自於網路或是依賴網路服務的功能,建議在 Resuming 時重新刷新內容或重新請求服務;
=>因為 Suspended 可能經過一段長時間,如果用戶返回 app 發現資料還是舊的也不合理。
如果 App 在 Suspend 狀態被藉由特定的 app contract 或 extension 加以啟動,App 會先被觸發 Resuming | resuming 事件,
接著才會進入 Activated | activated 事件。
當 App 進入 Suspend 狀態它不能接收任何網路事件(即時有註冊無用),這些事件不會被佇列起來,而是簡單的忽略。
所以如果 App 需要增加在測試在呼叫網路功能後,進入 Suspend 與 Resume 的狀態是否能正常運作。
詳細可參考<Guidelines for app suspend and resume.>、<How to resume an app (C#/VB/C++)>與<>。
[注意]
a. Windows Phone 環境下,從 Start Tile 或 App List 開啟該 App 均會被觸發,即使是 App 在 Suspend 狀態下;
b. Windows 環境下,從 Start Tile 或 App List 開啟該 App 在上一次是被終止或關閉才會被觸發,如果進入 Suspend 狀態下將不會再被觸發;
〉App close:
通常用戶不會關閉 App,交由系統本身管理。但用戶仍可以選擇關閉 App 藉由 task switcher (Windows Phone) 或 Alt + F4 (Windows)。
「不可以在 App 裡加上讓用戶可以關閉 App 的功能,如果加入將不會通過 Store certification process。」
相同地,用戶手動關閉了 App,其 App 本身不會收到任何的通知,這與被系統終止 App 的情境是一樣的。
當發生用戶關閉 App 後,App 的 suspended 與 terminated,並且 App 大約 10 秒內進入 NotRunning 的狀態。
但在 Windows 8.1 或更高階的版本,當用戶關閉了 App 只代表 App 從當前的 screen 或 task switcher 的 list 被移除,並不會進入 terminated。
需注意,如果您過去在 Windows 8 撰寫的 App 依賴 close-by-user 的行為,在升級至 Windows 8.1 之後仍然可以使用這樣的事件邏輯,
只需要在 Windows 8.1 app 多加上「在最後一個 window 使用 Windows.UI.ViewManagement.ApplicationView.TerminateAppOnFinalViewClose 來關閉 App」。
針對 close-by-user 的行為:
a. 建議可以用來判斷當 App 被啟動時加以檢查何種行為關閉了 App;
b. 不同的關閉行為將會影響 App 被重新開啟後要如何呈現;
c. 搭配 ApplicationExecutionState 判斷是為 ClosedByUser 或是 Terminated 來還原資料;
e. 建議應用程序沒有關閉自己編程,除非絕對必要。
例如,如果一個應用程序檢測到內存洩漏,它可以關閉本身,以確保用戶的個人數據的安全性。
當您以編程方式關閉一個應用程序,操作系統將此視為一個應用程序崩潰。
〉App crash:
App 被要求需遵守 system crash experience,當 App 當掉時需要簡單地回到 Start screen。
不建議在發生 App 當掉時提供一個警告對話框,或其他通知,因為這會造成對用戶的延遲。
如果 App 當掉、停止回應或是產生異常,Windows 系統會要求用戶同時回報問題至 Microsoft。這些回報的資料會進入 Dev Center。
開發人員就可以藉由這些資料來修正錯誤改善使用經驗。
〉App removal:
當使用者刪除了 App,該 App 所操作的 local data 也會被移除。但儲存於 Documents 與 Pictures 中的資料將會被保存。
例如:拍照的 App 刪除了 App 後,所拍下的照片仍存在設備裡面。
[注意事項]
a. 如果您使用電腦的 Administrator 帳戶登入,將無法啟用任何 Windows 市集應用程式。
======
這一篇介紹了入門 XAML App 開發的基本觀念,其實還有很多觀念與過去開發 Silverlight App 有很多要學習的。
下一篇將會針對實作的方式加以說明與討論,如果該篇寫的不清楚或是有些問題,也請多給我指導。謝謝。
References:
》Application lifecycle (Windows Runtime apps)
》App contracts and extensions (Windows Runtime apps)
》Windows Phone Store APP Lifecycle and Background Processing
》What's New in Windows Phone 8.1
》Quickstart: recording the screen with ScreenCapture (XAML) (背景捉取畫面)
》Handling the Back Button in a Windows Phone app (XAML) (全新的Back鍵處理邏輯)
》Handling Activated, Suspending and Resuming events using the Windows Runtime
》Guidelines for app suspend and resume
》Quickstart: Adding audio in a Windows Runtime app
》Quickstart: Downloading a file
》How to suspend an app (C#/VB/C++)
》The latest developer bits and advertising SDK; it’s time to //publish/
》Unity x Windows 2D 新功能展示與 Windows 平台開發技術分享
》Launching, resuming, and multitasking (XAML)
》Windows Phone Store APP Lifecycle and Background Processing