本篇沒有圖就是狂。
學習目標
- Application.Current.Properties 不死系儲存值物件
- App Lifecycle
- App class 和 Page class 全域變數溝通
假設你在 六.壹 最後一個範例程式按下一長串重要的數字,卻來了一通電話導致 App 中斷 ( terminate ),當你結束通話後重新開啟 App,你還是會希望此串數字是 存在 的吧!
當然系統不會聰明到自動幫你存下這些資料,所以這一小節教你如何在 App 中斷時,手動存下資訊。
Two facilities
當 App 中斷時,該如何儲存畫面上的資訊或狀態,並於下次打開 App 時復原。
Application class 利用以下兩個機制(Facilities),來幫忙完成這件事情:
- Properties,Dictionary<string, object> 類別,用來儲存值。
- OnStart, OnSleep, OnResume,這些方法就是我們所知道的應用程式生命週期 (application lifecycle)。
要使用這些機制,首先你要確定 App 中斷時哪些資訊需要被儲存,一般來說會將使用者設定存下,例如 App 字體大小、顏色等... 或是使用者輸入到一半的資料,都可以在 Porperties 新增一組 key-value 存下。
但若使用者要儲存較大的檔案文件,就不建議用 Properties 了,必須直接將大型文件存在手機內 ( 20 章會提到 I/O )。
Properties
儲存值:
Application.Current.Properties["displayLabelText"] = displayLabel.Text;
不用擔心 key 值不存在於 Properties,若不存在會自動新增一組新的 key-value。
復原值:
IDictionaryproperties = Application.Current.Properties; if(properties.ContainsKey("displayLabelText")) { displayLabel.Text = properties["displayLabelText"] as string; }
其實相當簡單,就是將值丟進 Properties,要用的時候再藉由 key 取出來,而這個 Application.Current.Properties 可以把他想成不死系的字典物件...
App Lifecycle
一般來說 Properties 會搭配 App lifecycle 一起使用,底下三個 function 可以在 App 看到:
最重要是 OnSleep 這方法,一般來說,當手機太久沒使用就會進入睡眠模式,一旦進入睡眠模式後,執行中的 App 就會被中斷並呼叫 OnSleep 方法。
問題來了,通常要儲存的值會出現在一般的 Page 類別內,而 OnSleep 方法存在於 App 類別...Page 和 App 勢必要透過一些方法溝通,才能於 App 內的方法儲存 Page 的值。
這裡提供一個方法,
可以先在 App 類別下宣告需要被儲存的變數 (全域):
在 OnSleep 時將此全域變數存入 Properties 內,而在 App 建構子時將 Properties 存下的值指派回全域變數:
上面範例為了避免拼字錯誤,所以先將 key 值用 displayLabelText 變數存下。
接著來看 Page 那一端:
App Lifecycle
一般來說 Properties 會搭配 App lifecycle 一起使用,底下三個 function 可以在 App 看到:
public class App : Application { public App() { … } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps } protected override void OnResume() { // Handle when your app resumes } }
最重要是 OnSleep 這方法,一般來說,當手機太久沒使用就會進入睡眠模式,一旦進入睡眠模式後,執行中的 App 就會被中斷並呼叫 OnSleep 方法。
若 App 是因為本身 crash 而關閉,就不會呼叫 OnSleep 方法。
測試 OnSleep 最簡單的方法就是當你在執行 App 時,按下 Home 或是 Back 鍵,就能將 App 中斷。
問題來了,通常要儲存的值會出現在一般的 Page 類別內,而 OnSleep 方法存在於 App 類別...Page 和 App 勢必要透過一些方法溝通,才能於 App 內的方法儲存 Page 的值。
這裡提供一個方法,
可以先在 App 類別下宣告需要被儲存的變數 (全域):
public class App : Application { public App() { … } public string DisplayLabelText { set; get; } }
在 OnSleep 時將此全域變數存入 Properties 內,而在 App 建構子時將 Properties 存下的值指派回全域變數:
namespace PersistentKeypad { public class App : Application { const string displayLabelText = "displayLabelText"; public App() { if (Properties.ContainsKey(displayLabelText)) { DisplayLabelText = (string)Properties[displayLabelText]; } MainPage = new PersistentKeypadPage(); } public string DisplayLabelText { set; get; } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps Properties[displayLabelText] = DisplayLabelText; } protected override void OnResume() { // Handle when your app resumes } } }
上面範例為了避免拼字錯誤,所以先將 key 值用 displayLabelText 變數存下。
接著來看 Page 那一端:
public class PersistentKeypadPage : ContentPage { Label displayLabel; Button backspaceButton; public PersistentKeypadPage() { //RESTORE // New code for loading previous keypad text. App app = Application.Current as App; displayLabel.Text = app.DisplayLabelText; } void OnButtonClicked(object sender, EventArgs args) { Button button = (Button)sender; displayLabel.Text += (string)button.StyleId; // Save keypad text. App app = Application.Current as App; app.DisplayLabelText = displayLabel.Text; } }
可以看到程式 Page 內都是透過 app.DisplayLabelText 這全域變數在運作,
利用全域變數這樣簡單的溝通,就能達到我們 App 中斷時存下畫面上的資訊 這目的。
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。