Trước khi sắn tay áo lập trình thì các bạn cũng cần hiểu được vòng đời của ứng dụng Windows phone và cách quản lý trạng thái của nó như thế nào, vì nêu như không hiểu được vòng đời của ứng dụng thì bạn sẽ gặp khó khăn khi gặp những trường hợp phải lưu cấu hình hệ thống, cũng như không biết vì sao ứng dụng của ta lại tự động mất hay các thông số bị reset….
Khác với Windows Phone 8.0, đối với Windows Phone 8.1 vòng đời của nó được thể hiện như sau (vẽ hình gì cũng được, đại khái là nó như vậy đó). Bạn cũng để ý là Windows Phone 8.0 khi nhấn nút Home rồi bấm nút Back thì nó sẽ không hiển thị lại ứng dụng; Windows Phone 8.1 thì khác nếu 1 ứng dụng đang chạy mà bạn nhấn nút Home sau đó bấm lại nút Back thì ứng dụng đó sẽ được hiển thị trở lại như cũ.
– Bạn chú ý rằng với một ứng dụng Windows Phone thì nó có 3 trường hợp chính:
+ Một là ứng dụng đang chạy (running) –> Người sử dụng quan sát thấy ứng dụng đầy đủ, tương tác được với ứng dụng, và ta cũng có thể gọi nó là Foreground Lifetime
+ Hai là ứng dụng không chạy (terminated)–> Tức là nó không còn sống trên cõi đời của Memory nữa
+ Ba là trạng thái tạm ngưng hoạt động (suspended) –> Ứng dụng vẫn còn sống trên cõi đời của Memory nhưng người sử dụng không tương tác được và nó sẽ bị rơi vào trạng thái Killable (tức là nó có thể bị hệ thống tước đoạt mạng sống bất cứ khi nào–> terminated). Ví dụ như ta đang thao tác với ứng dụng thì tự nhiên có cuộc gọi tới, thì ứng dụng cuộc gọi sẽ đè lên ứng dụng của ta –> ứng dụng của ta chuyển qua suspended.
Bạn cần phải phân biệt rõ trạng thái terminated và suspended nó khác nhau như thế nào, và phải hiểu được lý do vì sao suspended lại có thể đưa ứng dụng vào trạng thái Killable? nó có một vài lý do chính sau:
1) Hệ thống thiếu RAM và cần thu hồi khi có những yêu cầu khác được ưu tiên hơn
2) Hoặc có thể thiết bị gần hết PIN, hệ thống cần kill ứng dụng để tiết kiệm PIN
3) Hoặc người sử dụng khởi động lại thiết bị.
4) Và những lý do gì đó mà ta không biết…
Khi ứng dụng rơi vào trạng thái Suspended thì nguy cơ nó bị terminated là rất cao, và nếu như không bị terminated thì nó cũng có thể bị reset các biến và đối tượng…
Như vậy một vài câu hỏi đặt ra cho vòng đời là:
1) Ta làm gì khi ứng dụng rơi vào trạng thái Suspended
2) Khi ứng dụng đang thực thi và đang chuyển đổi trạng thái thì các sự kiện gì sảy ra
3) quản lý các trạng thái thay đổi như thế nào.
————————————
Khi viết lệnh quản lý sự thay đổi trạng thái của ứng dụng thì thường ta xử lý ở 2 cấp độ:
– Cấp độ ứng dụng (xử lý trong App.xaml.cs) – có 4 sự kiện chính:
[code language=”CSharp”]
//Sự kiện này sẽ được triệu gọi khi ứng dụng được thực thi và nó sẽ không
//bị gọi lại khi ứng dụng reactived (tức là chỉ chạy 1 lần đầu tiên duy nhất)
private void Application_Launching(object sender, LaunchingEventArgs e)
{
string msg = "Application_Launching";
}
//Sự kiện nay được triệu gọi khi ứng dụng được Activated (người sử dụng tương tác được)
// Lầu đầu khi ứng dụng chạy (Application_Launching) nó sẽ không được gọi, các lần sau nó sẽ tiếp tục
//được triệu gọi nếu như nó được activated (chuyển từ Suspended sang Foreground Lifetime)
private void Application_Activated(object sender, ActivatedEventArgs e)
{
string msg = "Application_Activated";
}
//Sự kiện sẽ được triệu gọi khi ứng dụng bị đưa vào trạng thái Suspend
//–> tức là khi nó che khuất ứng dụng, người sử dụng không thể tương tác
//Và nó sẽ không được triệu gọi khi sự kiện Closing sảy ra
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
string msg = "Application_Deactivated";
}
//Sự kiện được triệu gọi khi ứng dụng chuyển qua trạng thái đóng (terminate)
//và nó sẽ không thực thi khi ứng dụng vào trạng hái Deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
string msg = "Application_Closing";
}
[/code]
—>Ta thường lưu thông tin cấp ứng dụng trong sự kiện Application_Deactivated và khởi tạo lại thông tin trong sự kiện Application_Activated.
– Cấp độ trang (xử lý trong mỗi trang .xaml.cs) – có 2 sự kiện chính:
[code language=”csharp”]
//Sự kiện sảy ra khi trang được hiển thị Foreground
//Ta thường khởi tạo lại giá trị được lưu trữ trong hàm này
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Windows.Storage.ApplicationDataContainer localsetting =
Windows.Storage.ApplicationData.Current.LocalSettings;
if(localsetting.Values["data"]!=null)
{
txtData.Text = localsetting.Values["data"].ToString();
}
}
//sự kiện sảy ra khi trang bị đóng hoặc bị trang khác đè lên
//Ta thường lưu thông tin cấp độ trang trong hàm nay
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Windows.Storage.ApplicationDataContainer localsetting =
Windows.Storage.ApplicationData.Current.LocalSettings;
localsetting.Values["data"] = txtData.Text;
}
[/code]
Bạn cần chú ý thứ tự diễn ra các sự kiện:
– Đầu tiên sự kiện ở cấp độ ứng dụng sẽ sảy ra trước
– Sau đó mới tới sự kiện ở cấp độ trang.
tức là Nếu trong 1 Project bạn vừa xử lý trạng thái ở cấp độ ứng dụng và cấp độ trang, khi ứng dụng bị suspended thì tuần tự sảy ra như sau:
hàm Application_Deactivated sảy ra trước sau đó mới tới OnNavigatedFrom.
– Tui có cung cấp lệnh lưu và phục hồi thông tin ở trên, các bạn có thể áp dụng vào ứng dụng của mình.
Để các bạn có thể dễ dàng thực hành bài tập này thì làm theo từng bước như sau:
Bước 1:
Tạo một Project tên “LearnLifeCycle” như hình chụp dưới đây:
Chú ý là chọn “Blank App (Windows Phone Silverlight)”, từ này các ví dụ Tui sẽ sử dụng loại Project này.
Bước 2:
Tạo thêm 2 trang Page2.xaml và Page3.xaml như hình dưới đây:
Để tạo mới 1 trang thì bạn chỉ cần bấm chuột phải vào Project chọn/ Add/ New Item:
Màn hình Add New Item sẽ hiển thị ra như dưới đây:
Chọn các thông số như hình, rồi bấm nút Add bạn sẽ có kết quả như mong muốn (tạo được 1 trang mới). Tương tự như vậy bạn có thể thêm Page3.xaml vào ứng dụng.
Bước 3:
Tiến hành XAML và coding cho Mainpage.xaml như sau:
[code language=”csharp”]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using LearnLifeCycle.Resources;
namespace LearnLifeCycle
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
//Nếu còn về trước được
if (NavigationService.CanGoBack)
NavigationService.GoBack();//thì về trước
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
//xử lý chuyển qua trang mới
if(NavigationService.CanGoForward)
{
NavigationService.GoForward();
}
else
{
//tạo uri qua trang mới:
Uri newPage = new Uri("/Page2.xaml", UriKind.Relative);
//gọi lệnh chuyển trang
NavigationService.Navigate(newPage);
}
}
//Sự kiện sảy ra khi trang được hiển thị Foreground
//Ta thường khởi tạo lại giá trị được lưu trữ trong hàm này
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Windows.Storage.ApplicationDataContainer localsetting =
Windows.Storage.ApplicationData.Current.LocalSettings;
if(localsetting.Values["data"]!=null)
{
txtData.Text = localsetting.Values["data"].ToString();
}
}
//sự kiện sảy ra khi trang bị đóng hoặc bị trang khác đè lên
//Ta thường lưu thông tin cấp độ trang trong hàm nay
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Windows.Storage.ApplicationDataContainer localsetting =
Windows.Storage.ApplicationData.Current.LocalSettings;
localsetting.Values["data"] = txtData.Text;
}
}
}
[/code]
Tiếp tục ta thiết kế XAML cho Page2 và Page3 (2 trang này giống y xì nhau) chủ yếu dùng để test mà thôi:
Vì nó giống nhau nên phần XAML tui chỉ ví dụ 1 Page 2, Page 3 bạn tự copy + paste sang:
[code language=”Csharp”]
<phone:PhoneApplicationPage
x:Class="LearnLifeCycle.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<!–LayoutRoot is the root grid where all page content is placed–>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!–TitlePanel contains the name of the application and page title–>
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="page name 2" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!–ContentPanel – place additional content here–>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="14,0,10,0">
<Button x:Name="btnPrevious" Content="Go to Previous Page" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Click="btnPrevious_Click"/>
</Grid>
<Button x:Name="btnNext" Content="Go to Next Page" HorizontalAlignment="Left" Margin="37,106,0,0" VerticalAlignment="Top" Click="btnNext_Click" Grid.Row="1"/>
</Grid>
</phone:PhoneApplicationPage>
[/code]
Phần xử lý coding cho Page2.xaml.cs:
[code language=”csharp”]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace LearnLifeCycle
{
public partial class Page2 : PhoneApplicationPage
{
public Page2()
{
InitializeComponent();
}
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
NavigationService.GoBack();
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
if (NavigationService.CanGoForward)
NavigationService.GoForward();
else
{
Uri newpage = new Uri("/Page3.xaml", UriKind.Relative);
NavigationService.Navigate(newpage);
}
}
}
}
[/code]
Phần xử lý coding cho Page3.xaml.cs (giống page2):
[code language=”csharp”]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace LearnLifeCycle
{
public partial class Page3 : PhoneApplicationPage
{
public Page3()
{
InitializeComponent();
}
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
NavigationService.GoBack();
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
if (NavigationService.CanGoForward)
NavigationService.GoForward();
else
{
Uri newpage = new Uri("/MainPage.xaml", UriKind.Relative);
NavigationService.Navigate(newpage);
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
}
}
}
[/code]
Bây giờ Tui cần các bạn test các trường hợp sau:
1) Từ trang MainPage, nhập dữ liệu cho TextBox rồi bấm nút HOME
2) Sau đó nhấn nút Back
3) Từ MainPage nhập dữ liệu cho Textbox rồi chuyển qua trang 2
4) Từ trang 2 quay lại trang 1
5) Từ trang 2 qua trang 3
6) Từ trang 3 qua trang Mainpage.
Bài hướng dẫn kế tiếp tui sẽ trình bày về XAML và các control cơ bản trong Windows Phone 8.1, các bạn chú ý theo dõi.
Chúc các bạn thành công