WP8.1开发:后台任务详解(求推荐)
小梦今天给大家分享一下windows phone 8.1中的后台任务如何实现,许多应用都会用到后台任务,所以我们必须得掌握.
新建后台任务类:
首先我们先新建一个windows phone 8.1空白应用程序.然后请右键单击你的解决方案并依此选择“添加”->“新建项目”.选择 Windows 运行时组件项目类型,为该项目命名为Basktask.(名字都随便起了,只是为了后面方便)
在项目中,右键单击“引用”并选择“添加新引用”。在“解决方案”下,选择“项目”,然后选择Basktask.
将Basktask默认生成的类class1改为SimpleTask.并实现IBackgroundTask接口,在类中实现继承自接口的Run方法.
Run 方法是一个需要的入口点,当触发指定事件时,将调用该入口点;每个后台任务都需要该方法。
1 namespace Basktask 2 { 3 public sealed class SimpleTask:IBackgroundTask 4 { 5 public void Run(IBackgroundTaskInstance taskInstance)//后台任务入口 6 { 7 //后台需要执行的操作 8 } 9 }
如果你在后台任务中运行任何异步代码,则你的后台任务需要使用延迟。如果不使用延迟,则后台任务进程可能会意外终止(如果 Run 方法在完成异步方法调用之前完成)。调用异步方法之前,在 Run 方法中请求延迟。将延迟保存到某个全局变量以便可以从异步方法访问。完成异步代码之后声明延迟完成。 以下示例代码获取和保存延迟,并在异步代码完成后将其释放:
1 public void Run(IBackgroundTaskInstance taskInstance)//后台任务入口 2 { 3 4 deferral = taskInstance.GetDeferral(); 5 6 deferral.Complete(); 7 }
创建触发器对象
为了使得后台任务能够响应事件触发,我们需要注册触发器,当条件满足触发器被触发的时候,后台任务就会被执行.windows phone 8.1后台任务可以使用的触发器有SystemTrigger,TimeTrigger,LocationTrigger,
MaintenanceTrigger PushNotificationTrigger RfcommConnectionTrigger DeviceChangeTrigger
BluetoothSignalStrengthTrigger GattCharacteristicNotificationTrigger.
下面我们简单介绍一下:
SystemTrigger:
SystemTrigger是系统事件触发器,以下事件会引发该触发器:UserPresent/Away, NetworkStateChange, InternetAvailable, SessionConnected, ServicingComplete, TimeZoneChange 等
注:LockScreenApplicationAdded and LockScreenApplicationRemoved 在windows phone 8.1中不在支持.
用法如下:
第一个参数 triggerType 指定了将激活此后台任务的系统事件触发器的类型。第二个参数 OneShot 指定后台任务是否将在下次发生系统事件并触发后台任务时,或在每次系统事件发生时运行一次,直至任务注销为止。
1 SystemTrigger systemTrigger = new SystemTrigger(SystemTriggerType.InternetAvailable, false);
TimeTrigger:
如果后台任务需要周期性运行可以使用TimeTrigger .用法如下:
1 TimeTrigger timetrigger = new TimeTrigger(30, false);
注:最小时间间隔为 30分钟.
第二个参数 OneShot 指定后台任务是运行一次还是保持周期性运行。如果 OneShot 被设置为 true,则第一个参数 (FreshnessTime) 会指定在计划后台任务之前需等待的分钟数。如果 OneShot 被设置为 false,则 FreshnessTime 会指定后台任务的运行频率。
其余的触发器大家可以参考MSDN文档,用法都很简单.
创建后台任务对象:
1 var SampleTask = new BackgroundTaskBuilder(); //创建后台任务实例 2 SampleTask.Name = "SimpleBackTask"; //指定后台任务名称 3 SampleTask.TaskEntryPoint = "Basktask.SimpleTask";//指定后台任务名称 4 SampleTask.SetTrigger(timetrigger);//指定后台任务的触发器
添加后台任务运行条件(可选)
在触发器事件发生后,你可以添加条件控制任务何时运行。添加该条件之前,创建一个代表该条件的 SystemCondition 对象,该对象必须实际用于运行后台任务。在构造函数中,通过提供一个 SystemConditionType 枚举值指定必须满足的条件。
1 SystemCondition internetCondition = new SystemCondition(SystemConditionType.InternetAvailable); 2 SampleTask.AddCondition(internetCondition);
注册后台任务:
1 var access = await BackgroundExecutionManager.RequestAccessAsync(); 2 if (access == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity) 3 { 4 BackgroundTaskRegistration task = SampleTask.Register(); 5 } 6 else if (access == BackgroundAccessStatus.Denied) 7 { 8 await new MessageDialog("您已禁用后台任务或后台任务数量已达最大!").ShowAsync(); 9 }
注:在 windows phone 8.1中,注册后台任务之前必须调用RequestAccessAsync()方法!
在应用清单中生命后台任务:
后台任务调试:
若要调试后台任务,请在该任务的 Run 方法中设置一个断点。 在“调试位置”工具栏中,选择你的后台任务。这将导致系统立即调用 Run 方法。
- 在该任务的 Run 方法中设置一个断点。
- 按 F5 或点击“调试”>“启动调试”以部署和运行该应用。
- 应用启动后,切换回 Visual Studio。
- 确保显示“调试位置”工具栏。该工具栏位于“查看”>“工具栏”菜单。
- 在“调试位置”工具栏上,单击“挂起”下拉菜单,然后选择你的后台任务.
- Visual Studio 会在断点位置挂起执行。
- 按 F5 点击“调试”>“继续”以继续运行该应用。
- 按 Shift+F5 或点击“调试”>“停止调试”以停止调试。
下面我们来看一个实例:
1 namespace Basktask 2 { 3 public sealed class SimpleTask:IBackgroundTask 4 { 5 bool cancelRequested = false;// 用来表示是否已经请求取消后台任务 6 BackgroundTaskDeferral deferral = null;//后台任务的延时 7 ThreadPoolTimer periodicTimer = null;//计时器 8 uint progress = 0; //用于保存后台任务的进度 9 IBackgroundTaskInstance bTaskInstance = null;//提供对后台实例的访问 10 11 public void Run(IBackgroundTaskInstance taskInstance)//后台任务入口 12 { 13 taskInstance.Canceled += taskInstance_Canceled; 14 deferral = taskInstance.GetDeferral(); 15 bTaskInstance = taskInstance; 16 periodicTimer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler(PeriodicTimerCallback), TimeSpan.FromMinutes(5)); 17 18 } 19 20 private void PeriodicTimerCallback(ThreadPoolTimer timer) 21 { 22 if ((cancelRequested==false)&&(progress<100)) 23 { 24 progress += 10; 25 bTaskInstance.Progress = progress; 26 } 27 else 28 { 29 periodicTimer.Cancel(); 30 var settings = Windows.Storage.ApplicationData.Current.LocalSettings; 31 var key = bTaskInstance.Task.Name; 32 settings.Values[key] = (progress < 100) ? "Canceled" : "Completed"; 33 deferral.Complete(); 34 } 35 } 36 37 void taskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) 38 { 39 cancelRequested = true; 40 } 41 } 42 }
1 protected override void OnNavigatedTo(NavigationEventArgs e) 2 { 3 foreach (var task in BackgroundTaskRegistration.AllTasks) 4 { 5 if (task.Value.Name == "SimpleBackTask") 6 { 7 task.Value.Progress += Value_Progress; 8 task.Value.Completed += Value_Completed; 9 UpdateUI("后台任务已经存在",""); 10 } 11 } 12 } 13 14 private async void UpdateUI(string p1, string p2)//更新UI 15 { 16 await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 17 { 18 progressText.Text = p1; 19 statusText.Text = p2; 20 }); 21 } 22 //处理后台任务完成事件 23 void Value_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) 24 { 25 UpdateUI("100%", "后台任务完成!"); 26 } 27 //处理后台任务进度 28 void Value_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args) 29 { 30 var progress = args.Progress + "%"; 31 UpdateUI("后台任务进行中:", progress); 32 } 33 34 private async void registerButton_Click(object sender, RoutedEventArgs e) 35 { 36 TimeTrigger timetrigger = new TimeTrigger(30, false); 37 38 var SampleTask = new BackgroundTaskBuilder(); //创建后台任务实例 39 SampleTask.Name = "SimpleBackTask"; //指定后台任务名称 40 SampleTask.TaskEntryPoint = "Basktask.SimpleTask";//指定后台任务名称 41 SampleTask.SetTrigger(timetrigger);//指定后台任务的触发器 42 43 SystemCondition internetCondition = new SystemCondition(SystemConditionType.InternetAvailable); 44 SampleTask.AddCondition(internetCondition); 45 46 var access = await BackgroundExecutionManager.RequestAccessAsync(); 47 if (access == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity) 48 { 49 BackgroundTaskRegistration task = SampleTask.Register(); 50 task.Progress += Value_Progress; ; 51 task.Completed += Value_Completed; ; 52 UpdateUI("", "注册成功"); 53 54 registerButton.IsEnabled = false; 55 cancelButtton.IsEnabled = true; 56 57 var settings = Windows.Storage.ApplicationData.Current.LocalSettings; 58 settings.Values.Remove(task.Name); 59 } 60 else if (access == BackgroundAccessStatus.Denied)//用户禁用后台任务或后台任务数量已达最大 61 { 62 await new MessageDialog("您已禁用后台任务或后台任务数量已达最大!").ShowAsync(); 63 } 64 65 } 66 67 private void cancelButtton_Click(object sender, RoutedEventArgs e)//删除后台任务 68 { 69 foreach (var task in BackgroundTaskRegistration.AllTasks) 70 { 71 if (task.Value.Name == "SimpleBackTask") 72 { 73 task.Value.Unregister(true);//删除后台任务 74 } 75 } 76 registerButton.IsEnabled = true; 77 cancelButtton.IsEnabled = false; 78 UpdateUI("","后台任务取消"); 79 } 80 }
前台代码:
1 <Grid> 2 <StackPanel HorizontalAlignment="Center"> 3 4 <Button Name="registerButton" 5 Content="注册后台任务" 6 Click="registerButton_Click"></Button> 7 <Button Name="cancelButtton" 8 Content="取消后台任务" 9 Click="cancelButtton_Click"></Button> 10 <TextBlock Text=" 后台任务状态" 11 FontSize="25"></TextBlock> 12 <TextBlock Name="statusText" 13 Text="未注册" 14 FontSize="25"></TextBlock> 15 <TextBlock Text=" 后台任务进度" 16 FontSize="25"></TextBlock> 17 <TextBlock Text="未开始进行" 18 Name="progressText" 19 FontSize="25"> 20 21 </TextBlock> 22 23 </StackPanel> 24 </Grid>