Windows 8 #2 – Uygulama Yaşam Döngüsü ve Durum Yönetimi
Windows 8”de, sistemin yavaşlaması ve batarya kullanımını dert etmeden bir sürü uygulamayı aynı anda açabilirsiniz. Windows 8 işletim sistemi, sizin için arkaplanda, uygulamaların hazır bekletilmesine olanak tanır. İyi bir Windows 8 uygulaması geliştirirken, uygulamanın bekletilmesi, beklemeden sonra tekrar çalıştırılabilmesi, kapanması durumlarını göz önünde bulundurmak gerekiyor.
Bu eğitimde:
- Kaydetme durumunda(Save State), farklı depolama alanlarına kayıtların gerçekleştirilmesi,
- Uygulamanın tekrar çalıştırılması durumunda, uygulamanın son durumunu korumayı öğreneceğiz.
Başlamadan önce…
- Windows 8 Merhaba Dünya Uygulaması ”na bakmanızı tavsiye ediyorum.
- Bu bölümün kodlarını buradan indirebilirsiniz.
Uygulamanın Yaşam Döngüsü Hakkında
Kod kısmına geçmeden önce kısaca yaşam döngüsünden bahsedelim. Uygulamanın 3 tane eylemi bulunmaktadır. Bunlar Running(Çalışıyor), NotRunning(Çalışmıyor), bir de Suspended(Bekliyor).
Uygulamamız, başka bir uygulama başlatıldığında veya Windows düşük batarya durumuna geçtiğinde, “Bekliyor” konumuna geçebilir. Bu durumda hafızada uygulamaya belli yer ayrılır ki, tekrar uygulama açıldığında hızlıca kaldığı yerden devam edebilsin. Ayrıca çeşitli nedenlerle Windows”un kendisi de bu uygulamayı kapatabilir. Bunu yapmadan önce uygulamaya bildirir. Böylece uygulama kapanmadan önce verilerin kaybı sorunu çözülmüş olur.
Sonraki adımda app data ve session data ”yı nasıl güncelleyeceğimizi öğreneceğiz.
1.SuspensionManager Kullanımı
Merhaba Dünya uygulamasını yaparken kullandığımız Basic Page şablonu, Common klasörüne birkaç dosya eklemiştir. Bunlardan biri olan SuspensionManager sayesinde uygulamamızın yaşam döngüsünü daha kolay bir biçimde kontrol edebilmekteyiz. Sayfalar arası geçiş sırasında, uygulamanın sayfalarını tutan Frame‘in geçiş durumunu kaydetmek ve geri yüklemek, tek sayfaya sahip uygulamalar için bir önemi olmasa da, birden çok sayfaya sahip uygulamalarda çok önem kazanmaktadır. Bu sınıf, sayfa durumu verisini XML dosyası halinde, uygulamanın lokalinde barındırır.
SuspensionManager sınıfını kullanabilmek için, ilk olarak ana Frame”i kaydetmek gerekiyor. Bu işlem tamamlandığında , bu sınıf, uygulamanın herbir sayfasından haberdar olacaktır. Bu kayıt işlemini gerçekleştirmek, App.xaml.cs içindeki OnLaunched metodunun oluşturulmasından hemen sonra olacaktır.
Bu sınıfın kullanımı için;
- Solution Explorer penceresinden App.xaml.cs”e çift tıklayıp açıyoruz.
- OnLaunched metodunda aşağıdaki değişiklikleri yaparak, Frame”i kaydetmiş oluyoruz.
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
MerhabaDunya.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame");<br>
2.Uygulamanın Durumunun Kaydedilmesi
Uygulamamızda kontrol etmemiz gereken 2 tip veri çeşidi vardır: app data ve session data. App data, TextBox”ımızın Text”idir. Uygulamanın bekleme moduna geçerken 5 saniyesi vardır. Bu süre içerisinde önemli app data”ları bir an önce kaydetmek gerekir.
Windows.Storage.ApplicationData objesiyle app data”mızı yönetebiliriz. Bu obje, ApplicationDataContainer”i döndüren, RoamingSettings özelliğine sahiptir.
App data”yı kaydetmek için;
- MainPage.xaml”a çift tıklıyoruz.
- Bir tane TextBox sürükleyip bırakıyoruz ve Name niteliğini belirliyoruz. Benim kodda TextBox1 olarak geçiyor.
- Properties penceresinde, olaylar butonuna
tıklıyoruz.
- TextChanged olayının yanındaki textbox”a çift tıklıyoruz.
- Metodumuzda aşağıdaki şekilde TextBox”ımızın Text niteliğini kaydediyoruz. Sonrasında F5”e basıp uygulamamızı çalıştırıyoruz. TextBox içerisine yazdığınız isminiz kaydedilmiş olacaktır.
Windows.Storage.ApplicationDataContainer dolasimAyarlari = Windows.Storage.ApplicationData.Current.RoamingSettings;
dolasimAyarlari.Values["kullaniciAdi"] = TextBox1.Text;
Session data, ilgili kullanıcının o anki uygulamadaki oturumunun saklandığı geçici veridir. Bir oturum, kullanıcı kapatma hareketini yaptığında ya da Alt + F4 kısayolunu kullandığında, bilgisayarını tekrardan başlattığında, ya da bilgisayarı kapattığında sona erer. Bizim uygulamamızda ise, greetingOutput TextBlock”unun Text özelliği session data”dır. Bu veriyi, Windows uygulamanızı beklettiğinde ya da sonlandırdığında yenileyebilirsiniz. Öncelikle bizim uygulamamızın Frame”inin navigasyon durumunu kaydetmeliyiz ki, bu sayede uygulama uygulama açıldığında, kendini son kapatıldığı andaki sayfadan başlatabilsin ve SuspensionManager hangi sayfanın durumunun tekrar yüklenmesi gerektiğini bilebilsin. Bununla birlikte sayfamızın kendisinin durumunu da kaydetmemiz gerekiyor. Hatırladığınız gibi greetingOutput”un Text özelliğini buraya kaydetmiştik.
Session data”yı kaydetmek için;
- App.xaml.cs”i Solution Explorer penceresinden bulup açıyoruz.
- App.xaml.cs içerisinde, OnSuspending metodunun başına async anahtar kelimesini ekliyoruz.
- OnSuspending metodu içerisinde, SuspensionManager.SaveAsync metodunu çağırıyoruz. SaveAsync metodunu çağırmak, Frame”in navigasyon durumunu kaydeder ve sayfanızın içeriğinin kaydedilmesine olanak sağlar.
async private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); //TODO: Save application state and stop any background activity await MerhabaDunya.Common.SuspensionManager.SaveAsync(); deferral.Complete(); }
- MainPage.xaml.cs sayfasını Solution Explorer penceresinden bulup çift tıklayın.
- MainPage.xaml.cs sayfasındaki SaveState metodu içerisini aşağıdaki gibi düzenleyerek sayfanın durumunu kaydedin.\r\n
protected override void SaveState(Dictionary<String, Object> pageState) { pageState["greetingOutputText"] = greetingOutput.Text; }
- Veriler pageState(SaveState metodunun hemen üzerindeki .xml dosyasında tanımlanmıştır.) içerisinde sadece bu oturum için saklanmıştır. Yukarıdaki ifadede de greetingOutput.Text”i kaydetmiş olduk. Şimdi Build -> Build Solution yaparak uygulamamızda herhangi bir hata olmadığından emin olalım.
Uygulama sonlandırılmadan önce uygulamamızın durumunu kaydetmeyi öğrendik. Şimdi ise uygulamımızın tekrar çalıştırılması durumunda uygulamamızın durumu geri yüklemeyi öğreneceğiz.
3.Uygulamanın Durumunu Tekrar Yüklemek
Şimdi App.xaml.cs dosyasına yani uygulamanın aktivasyonlarının yönetimine bir bakalım.
Öncelikle, aşağıdaki kodda bir Frame”in tanımlandığını ve o andaki pencerenin içeriğine atandığını görüyoruz.
Frame rootFrame = Window.Current.Content as Frame;
Tabi penceremiz bir Frame‘e sahipse, bu tanımlamayı yapmaya gerek yoktur.
Aşağıdaki kodda uygulamanın sonki kapatılmasından önceki çalıştırılma durumunu kontrol ediliyor. Önceki çalıştırılma durumu Sonlandırıldı(Terminated) olması, Windows”un başarılı bir şekilde bekletilip(Suspend) daha sonra sonlandırıldığı anlamına gelmektedir. Bu durumda o zamanki uygulamanın durumu geri yüklenecektir.
if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); MerhabaDunya.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame"); if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: Load state from previously suspended application\r\n } // Place the frame in the current Window Window.Current.Content = rootFrame; } }
Bir sonraki kod is Frame”in herhangi bir içeriğe sahip olup olmadığını kontrol edecektir. Eğer uygulama çalışıyor durumda is ya da navigasyon durumu geri yüklenmiş(Restored) ise, Frame”in içeriği mevcuttur. Değilse, Frame kendisini uygulamanın ilk sayfasına yönlendirecektir. Yani bu örnekte MainPage”e yönlendirmiş olacak.
if (rootFrame.Content == null) { // 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(typeof(MainPage), args.Arguments)) { throw new Exception("Failed to create initial page"); } }
Ve son olarak kodumuz, penceremizi aktif hale getirir.
Window.Current.Activate();
Artık uygulama başlatıldığında neler olduğunu biliyoruz, şimdi de nasıl uygulamanın durumunu geri yükleriz ona bakalım.
Uygulamanın Durumunu Geri Yüklemek
- App.xaml.cs içerisinde, OnLaunched metodunun imza kısmına async anahtar kelimesini ekleyelim.
async private void OnSuspending(object sender, SuspendingEventArgs e)
-
- Uygulama sonlandırılmış ise, SuspensionManager.RestoreAsync metodunu çağırmalıyız. Bu metodu çağırmak Frame”imizin navigasyon durumunu tekrardan yükleyip ve sonrasında sayfamızın(Page) içeriğinin tekrardan yüklenmesine olanak tanıyacaktır.
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: Load state from previously suspended application
-
- await MerhabaDunya.Common.SuspensionManager.RestoreAsync(); }
-
- MainPage.xaml.cs içerisinde, LoadState metoduna, sayfa durumunun geri yüklenmesi için aşağıdaki kodu ekleyelim
- Öncelikle, greetingOutputText isimli anahtara sahip pageState sözlüğü var mı yok mu kontol edelim. Eğer anahtar mevcutsa, greetingOutput”un Text”ini bu anahtar aracılığıyla geri yükleyelim.
-
if (pageState != null && pageState.ContainsKey("greetingOutputText")) greetingOutput.Text = pageState["greetingOutputText"].ToString();
-
-
- Sonra kullanıcı adını yükleyelim. Çünkü kullanıcı adı verisiyle birden fazla oturumun bilgisine ulaşıp, geri yüklenmesi işlemini gerçekleştireceğiz. Bu veriyi de RoamingSettings uygulama veri konteynerinde depoluyoruz. Şimdi kullanıcı adının var olup olmadığını kontrol edip, eğer varsa kullanıcı adını gösterelim.
Windows.Storage.ApplicationDataContainer dolasimAyarlari = Windows.Storage.ApplicationData.Current.RoamingSettings; if (dolasimAyarlari.Values.ContainsKey("kullaniciAdi")) TextBox1.Text = dolasimAyarlari.Values["kullaniciAdi"].ToString();
LoadState metodu aşağıdaki gibi olacaktır.
/// <summary> /// Populates the page with content passed during navigation. Any saved state is also /// provided when recreating a page from a prior session. /// </summary> /// <param name="navigationParameter">The parameter value passed to /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested. /// </param> /// <param name="pageState">A dictionary of state preserved by this page during an earlier /// session. This will be null the first time a page is visited.</param> protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { if (pageState != null && pageState.ContainsKey("greetingOutputText")) greetingOutput.Text = pageState["greetingOutputText"].ToString(); Windows.Storage.ApplicationDataContainer dolasimAyarlari = Windows.Storage.ApplicationData.Current.RoamingSettings; if (dolasimAyarlari.Values.ContainsKey("kullaniciAdi")) TextBox1.Text = dolasimAyarlari.Values["kullaniciAdi"].ToString(); }
Artık uygulamamızı çalıştırdığımızda yapmış olduğumuz oturum durumunu kaydetme ve geri yükleme işlemlerini görebiliriz. Fakat şöyle bir durum var, uygulamamızı çalıştırıp TextBox1 içerisine veriyi girdikten sonra Debug -> Stop Debugging yaptığımızda bekletme(Suspending) işlemi gerçekleşmeyecektir.
Bekletme(Suspending), sonlandırma(Terminating) ve geri yükleme(Restore) işlemlerini gerçekleştirmek için
-
-
- F5”e basarak uygulamamızı debug modda çalıştırıyoruz.
-
- İsmimizi TextBox”a girip “Merhaba Dünya” butonuna tıklıyoruz. Karşılama, ekranda gözüküyor.
-
- Şimdi Alt+Tab yapıp Visual Studio”ya dönelim.
-
- Suspend yazılı yeri genişletelim ve Suspend and Shutdown”a tıklayalım.
- Suspend yazılı yeri genişletelim ve Suspend and Shutdown”a tıklayalım.
-
- F5”e basalım ve uygulamayı tekrardan çalıştıralım. Uygulamamuz önceki durumuna geri yüklendi.
-
- TextBox içerisindeki ismi değiştirip, “Merhaba Dünya” butonuna tıklayalım.
-
- Alt+Tab yapıp Visual Studio”ya dönerek Debug -> Stop Debugging diyoruz.
-
- F5 ile tekrar uygulamayı çalıştırıyoruz.
-
Kullanıcı adı geri yüklendi çünkü o yazarken kaydediliyordu. Karşılama ise geri yüklenmedi. Çünkü uygulama bekletilmedi(Suspend) ve oturumun durumu kaydedilmemiş oldu.
Kaynak : Windows Store app using C# or Visual Basic, Getting Started Guide – http://msdn.microsoft.com/en-us/library/windows/apps/hh974581.aspx
-