Windows phone 8 学习笔记(6) 多任务(转)
2020-12-13 05:50
标签:des style blog http 使用 os io 文件 Windows phone 8 是一个单任务操作系统,任何时候都只有一个应用处于活跃状态,这里的多任务是指对后台任务的支持。本节我们先讲讲应用程序的运行状态,然后看看支持的后台任务,包括:后台代理、后台音频、后台文件传输、后台辅助线程等。 快速导航: 我们通过图解来分析应用的运行状态,启动并置于前台界面的应用是唯一处于运行状态的,其他的操作,比如win键,后退导出应用,打开选择器和启动器时都会让当前运行的应用进入休眠状态,如果系统内存不足,处于休眠状态的应用可能会被系统逻辑删除。下面的图示演示了这个过程。 当应用处于休眠状态时,它的状态信息仍然保留在内存中,用户下次切换进去后不会有任何变化。但是当应用被逻辑删除后,这些状态信息就会丢失,比如表单填写的内容都会消失,为了避免这种情况,我们需要手动保留状态信息。 [XAML] 我们需要实现在应用逻辑删除后能将其状态保持到页面的State字典中,但是需要我们的数据源支持序列化,所以我们定义与表单关联的ViewModel如下:
[C#] 我需要对mainpage代码添加页面导航入、导航出的事件。导航出页面的时候,如果不是向后导航,则存储状态。导航入的时候,我们需要判断页面是否为逻辑删除后正在恢复的状态,如果是,则通过状态字典恢复状态。mainpage代码如下:
[C#] 然后我们添加一page1页面,该页添加一个返回按钮。用于测试。为了达到调试时即时进入逻辑删除的效果,我们需要设置下。右键项目文件,点属性,在调试选项卡勾选“在调试期间取消激活时逻辑删除”。
后台代理可以在应用退出以后独立在系统后台运行,它包含两种类型的代理,分别是定期代理和资源密集型代理,前者用于频繁执行小任务,后者用于在系统空闲时执行耗时大任务。要使用后台代理,我们需要添加一个名为Windows phone 计划任务代理的项目,并在应用的项目中添加对其的引用,现在我们要实现在后台代理中弹出Toast,我们需要如下修改ScheduledAgent.cs的OnInvoke方法,代码如下
[C#] 接着,我们在应用项目的mainpage中调用代理,代码如下:
[XAML] [C#] 通过后台音频的功能我们可以实现在系统后台播放音乐的功能,由于后台音频代理只能访问本地文件夹,所以我们务必要先把需要播放的音乐文件拷贝到本地文件夹中。本示例是把安装文件夹的音频文件拷贝到本地文件夹,代码如下:
[C#] 我们需要在解决方案中添加Windows phone 音频播放代理项目,并在应用项目中添加对其的引用。修改AudioPlayer.cs代码如下:
[C#] 最后,我们在mainpage中添加对播放的控制。
[XAML] [C#] 后台文件传输允许我们实现下载上传文件的功能,他限制系统中同时运行的传输任务不能超过两个,并且下载的文件只能存放在本地文件夹的/shared/transfers目录下。下面我们实现一个后台传输任务,下载博客相册中的一张照片。
[XAML] [C#] 后台辅助线程虽然名字这么叫,但是它不能在后台运行,我们可以用它来执行一个任务,并且可以实时获取执行的进度,实现代码如下:
[XAML] [C#] Windows phone 8 学习笔记(6) 多任务(转),搜素材,soscw.com Windows phone 8 学习笔记(6) 多任务(转) 标签:des style blog http 使用 os io 文件 原文地址:http://www.cnblogs.com/jx270/p/3886405.html
一、应用的状态
二、后台代理
三、后台音频
四、后台文件传输
五、后台辅助线程 一、应用的状态
1)应用的运行状态
2)如何恢复状态
首先,我们在mainpage定义一些页面表单控件:
[DataContract]
public class ViewModel : INotifyPropertyChanged
{
private string _textBox1Text;
private bool _checkBox1IsChecked;
private bool _radioButton1IsChecked;
private bool _radioButton2IsChecked;
private double _slider1Value;
[DataMember]
public string TextBox1Text
{
get { return _textBox1Text; }
set
{
_textBox1Text = value;
NotifyPropertyChanged("TextBox1Text");
}
}
[DataMember]
public bool CheckBox1IsChecked
{
get { return _checkBox1IsChecked; }
set
{
_checkBox1IsChecked = value;
NotifyPropertyChanged("CheckBox1IsChecked");
}
}
[DataMember]
public double Slider1Value
{
get { return _slider1Value; }
set
{
_slider1Value = value;
NotifyPropertyChanged("Slider1Value");
}
}
[DataMember]
public bool RadioButton1IsChecked
{
get { return _radioButton1IsChecked; }
set
{
_radioButton1IsChecked = value;
NotifyPropertyChanged("RadioButton1IsChecked");
}
}
[DataMember]
public bool RadioButton2IsChecked
{
get { return _radioButton2IsChecked; }
set
{
_radioButton2IsChecked = value;
NotifyPropertyChanged("RadioButton2IsChecked");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (null != PropertyChanged)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainPage : PhoneApplicationPage
{
// 构造函数
public MainPage()
{
InitializeComponent();
_isNewPageInstance = true;
}
ViewModel _viewModel = null;
///
二、后台代理
protected override void OnInvoke(ScheduledTask task)
{
string toastMessage = "";
if (task is PeriodicTask)
{
toastMessage = "定期代理正在运行";
}
else
{
toastMessage = "资源密集型代理正在运行";
}
// 用于向用户显示Toast,如果当前任务的前台正在运行,则不显示
ShellToast toast = new ShellToast();
toast.Title = "标题";
toast.Content = toastMessage;
toast.Show();
// 在调试的时候需要及时执行查看效果
#if DEBUG_AGENT
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(15));
#endif
NotifyComplete();
}
public partial class MainPage : PhoneApplicationPage
{
///
三、后台音频
//把安装文件夹下的文件拷贝到本地文件夹
private void CopyToIsolatedStorage()
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
string[] files = new string[] { "Ring01.wma", "Ring02.wma", "Ring03.wma" };
foreach (var _fileName in files)
{
if (!storage.FileExists(_fileName))
{
string _filePath = "Audio/" + _fileName;
StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));
using (IsolatedStorageFileStream file = storage.CreateFile(_fileName))
{
int chunkSize = 4096;
byte[] bytes = new byte[chunkSize];
int byteCount;
while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
{
file.Write(bytes, 0, byteCount);
}
}
}
}
string[] icons = new string[] { "Ring01.jpg", "Ring02.jpg", "Ring03.jpg" };
foreach (var _fileName in icons)
{
if (!storage.FileExists(_fileName))
{
string _filePath = "Images/" + _fileName;
StreamResourceInfo iconResource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));
using (IsolatedStorageFileStream file = storage.CreateFile( _fileName))
{
int chunkSize = 4096;
byte[] bytes = new byte[chunkSize];
int byteCount;
while ((byteCount = iconResource.Stream.Read(bytes, 0, chunkSize)) > 0)
{
file.Write(bytes, 0, byteCount);
}
}
}
}
}
}
public class AudioPlayer : AudioPlayerAgent
{
private static volatile bool _classInitialized;
private static List _playList = new List
{
new AudioTrack(new Uri("Ring01.wma", UriKind.Relative),"曲目1","艺术家1","专辑1",new Uri("Ring01.jpg", UriKind.Relative)),
new AudioTrack(new Uri("Ring02.wma", UriKind.Relative),"曲目2","艺术家2","专辑2",new Uri("Ring02.jpg", UriKind.Relative)),
new AudioTrack(new Uri("Ring03.wma", UriKind.Relative),"曲目3","艺术家3","专辑3",new Uri("Ring03.jpg", UriKind.Relative))
};
///
public partial class MainPage : PhoneApplicationPage
{
// 构造函数
public MainPage()
{
InitializeComponent();
BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);
}
//刚加载时确定播放状态
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
button1.Content = "■";
textblock1.Text = "曲目:" + BackgroundAudioPlayer.Instance.Track.Title
+ " 艺术家:" + BackgroundAudioPlayer.Instance.Track.Artist
+ " 专辑:" + BackgroundAudioPlayer.Instance.Track.Album
+ " 曲目长度:" +BackgroundAudioPlayer.Instance.Track.Duration.Minutes + ":" + BackgroundAudioPlayer.Instance.Track.Duration.Seconds;
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
var stream = storage.OpenFile(BackgroundAudioPlayer.Instance.Track.AlbumArt.OriginalString, System.IO.FileMode.Open);
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
imge1.Source = bitmapImage;
stream.Close();
}
}
else
{
button1.Content = "?";
textblock1.Text = "未播放曲目";
}
}
void Instance_PlayStateChanged(object sender, EventArgs e)
{
switch (BackgroundAudioPlayer.Instance.PlayerState)
{
case PlayState.Playing:
button1.Content = "■";
button2.IsEnabled = true;
button3.IsEnabled = true;
break;
case PlayState.Paused:
case PlayState.Stopped:
button1.Content = "?";
break;
}
if (null != BackgroundAudioPlayer.Instance.Track && BackgroundAudioPlayer.Instance.PlayerState!= PlayState.Stopped)
{
textblock1.Text = "曲目:" + BackgroundAudioPlayer.Instance.Track.Title
+ " 艺术家:" + BackgroundAudioPlayer.Instance.Track.Artist
+ " 专辑:" + BackgroundAudioPlayer.Instance.Track.Album
+ " 曲目长度:" + BackgroundAudioPlayer.Instance.Track.Duration.Minutes + ":" + BackgroundAudioPlayer.Instance.Track.Duration.Seconds;
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
var stream = storage.OpenFile(BackgroundAudioPlayer.Instance.Track.AlbumArt.OriginalString, System.IO.FileMode.Open);
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
imge1.Source = bitmapImage;
stream.Close();
}
}
}
//播放/暂停
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
BackgroundAudioPlayer.Instance.Pause();
else
BackgroundAudioPlayer.Instance.Play();
}
//向前
private void Button_Click_2(object sender, RoutedEventArgs e)
{
BackgroundAudioPlayer.Instance.SkipPrevious();
button2.IsEnabled = false;
}
//向后
private void Button_Click_3(object sender, RoutedEventArgs e)
{
BackgroundAudioPlayer.Instance.SkipNext();
button3.IsEnabled = false;
}
}
四、后台文件传输
public partial class MainPage : PhoneApplicationPage
{
// 构造函数
public MainPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
initTransferRequest();
base.OnNavigatedTo(e);
}
private void initTransferRequest()
{
//获取第一个后台传输任务
var transferRequest = BackgroundTransferService.Requests.FirstOrDefault();
if (transferRequest == null)
{
textblock1.Text = "无后台传输任务";
button1.IsEnabled = true;
return;
}
//当传输状态改变时:
transferRequest.TransferStatusChanged += new EventHandler
五、后台辅助线程
public partial class MainPage : PhoneApplicationPage
{
private BackgroundWorker bw = new BackgroundWorker();
public MainPage()
{
InitializeComponent();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
}
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
}
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
if (bw.WorkerSupportsCancellation == true)
{
bw.CancelAsync();
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i
下一篇:26.删除排序数组中的重复项
文章标题:Windows phone 8 学习笔记(6) 多任务(转)
文章链接:http://soscw.com/essay/31835.html