说到后台任务,这是在和许多 Android 开发者聊天的时候,经常被提起的话题之一, Windows 移动平台的后台任务的形式有别与 Android 的后台 service,简单的说在 Windows RT 移动平台下只有在满足一定条件的时候才能运行一部分预先设置好的制的代码。并且 Windows 8.1 和 Windows Phone 8.0 对后台任务有些区别,今天我就为大家介绍一下 Windows 8.1 移动平台下的后台任务,以及他们的运行条件。
首先给大家介绍下 Windows 移动平台的应用运行后台的情景分为多种。
今天我只为大家介绍以下基础任务,后台任务响应系统事件 ( 后台任务的运行条件、ServicingComplete - 应用更新触发器 )、维护触发器、计时器后台任务,这些内容后面我一个一个的给大家介绍。
在此之前我先介绍下使用后台的应用配置。
手动在 Package.appxmanifest 文件中声明支持的后台任务类型
声明在 <Extensions> 节点中
<Application Id="BackgroundTaskSample.App" Executable="BackgroundTaskSample.exe" EntryPoint="BackgroundTaskSample.App"><VisualElements DisplayName="BackgroundTaskSample" Logo="Images\squareTile-sdk.png" SmallLogo="Images\smallTile-sdk.png" Description="BackgroundTaskSample" ForegroundText="dark" BackgroundColor="#222222"><LockScreen Notification="badgeAndTileText" BadgeLogo="images\badgelogo.png"/><DefaultTile ShowName="allLogos" WideLogo="images\tile-sdk.png"/><SplashScreen Image="Images\splash-sdk.png" BackgroundColor="#FFFFFF"/></VisualElements><Extensions><!-- TODO: Add elements here --></Extensions></Application>
例如:
<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.BackgroundTaskClass"><BackgroundTasks><Task Type="systemEvent"/><Task Type="pushNotification"/></BackgroundTasks></Extension>
或者直接在 图形化界面中鼠标勾选 注意:这里要手动输入一个:Entry Point 这个字段很重要,这个字段要和后面 BackgroundTaskBuilder.TaskEntryPoint 注册任务时传入的参数一致(为了声明后台代理的权限以及要运行代理逻辑的命名空间)
对于后台任务代码实现部分简单的说分为两个部分:
第一部分:运行的逻辑体本身(业务逻辑部分)你需要创建一个后台任务类(具体步骤借用MSDN原话)
你可以通过编写用于实现 IBackgroundTask接口的类来在后台运行代码。在使用诸如 SystemTrigger或 MaintenanceTrigger等触发器触发特定事件时,将运行该代码。
以下步骤介绍如何编写实现 IBackgroundTask接口的一个新类。开始之前,在解决方案中为后台任务创建一个新项目。为后台任务添加一个新的空类,并导入Windows.ApplicationModel.Background命名空间。
- 为后台任务创建一个新项目并将其添加到你的解决方案。为此,请右键单击你的解决方案并选择“添加”->“新建项目”。然后选择 Windows 运行时组件项目类型,命名项目,并单击“确定”。
- 从 Windows 应用商店应用引用后台任务项目。首先,右键单击你的 Windows 应用商店应用项目并选择“属性,然后转到“常见属性”并单击“添加新参考”,选中后台任务项目旁边的复选框,然后单击两个对话框中的“确定”。
创建一个实现 IBackgroundTask接口的新类。Run方法是在触发指定的事件时必须调用的输入点;每个后台任务中都需要该方法。
注意 后台任务类本身(以及后台任务项目中的所有其他类)必须是属于 sealed的 public类。
//// ExampleBackgroundTask.cs//using Windows.ApplicationModel.Background;namespace Tasks {publicsealedclass ExampleBackgroundTask : IBackgroundTask {publicvoid Run(IBackgroundTaskInstance taskInstance) { BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();//// TODO: Insert code to start one or more asynchronous methods using the// await keyword, for example://// await ExampleMethodAsync();// _deferral.Complete(); } } }
第二部分:在应用程序中注册后台的代理 (在注册后台代理的时候可以 选择后台代理的类型以及代理的运行条件)
步骤 1: 定义方法签名并返回类型
此方法包含任务入口点、任务名称、预构建的后台任务触发器以及后台任务的SystemCondition(可选)。此方法返回 BackgroundTaskRegistration对象。
下面是捕获系统事件的情况下激发后台任务,这里叫做 SystemTrigger
实际 8.1 SDK 中枚举选项会多一些。
为了我们后台代理执行的有效性 例如:只有在机器联网的情况下执行后台代理,windows移动平台的后台代理 为我们提供了 后台任务的执行条件选择的机会。由 SystemConditionType 枚举表示,在Win8.1 SDK 中实际会比截图中的选项更多一些
这里有一个注册后台代理的代码给大家参考下(可以直接使用。 注:这里的 condition 其实是支持添加多个的)
//// Register a background task with the specified taskEntryPoint, name, trigger,// and condition (optional).//// taskEntryPoint: Task entry point for the background task.// taskName: A name for the background task.// trigger: The trigger for the background task.// condition: Optional parameter. A conditional event that must be true for the task to fire.//publicstatic BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint,string taskName, IBackgroundTrigger trigger, IBackgroundCondition condition) {//// Check for existing registrations of this background task.//foreach (var cur in BackgroundTaskRegistration.AllTasks) {if (cur.Value.Name == taskName) {//// The task is already registered.//return (BackgroundTaskRegistration)(cur.Value); } }//// Register the background task.//var builder = new BackgroundTaskBuilder(); builder.Name = taskName; builder.TaskEntryPoint = taskEntryPoint; builder.SetTrigger(trigger);if (condition != null) { builder.AddCondition(condition); } BackgroundTaskRegistration task = builder.Register();return task; }
ServicingComplete 触发器
写ServicingComplete 触发器的方法体的方法上面事件触发器的形式是一致的。这个触发器的作用顾名思义 就是当应用更新完成以后激发。
除了SystemTrigger 还有 MaintenanceTrigger维护触发器
使用维护触发器每 15 分钟运行一次任务。维护任务仅在设备插入交流电源时运行,而无需位于锁屏上。这里我还是引用一下 MSDN
创建新的 MaintenanceTrigger对象。第二个参数 OneShot指定维护任务是运行一次还是继续定期运行。如果 OneShot被设置为 true,则第一个参数 (FreshnessTime) 会指定在计划后台任务之前需等待的分钟数。如果 OneShot被设置为 false,则 FreshnessTime会指定后台任务的运行频率。
注意 如果 FreshnessTime设置为少于 15 分钟,则在尝试注册后台任务时将引发异常。
int waitIntervalMinutes = 60; MaintenanceTrigger taskTrigger = new MaintenanceTrigger(waitIntervalMinutes, false); SystemCondition exampleCondition = new SystemCondition(SystemConditionType.InternetAvailable);string entryPoint = "Tasks.ExampleBackgroundTaskClass";string taskName = "Maintenance background task example"; BackgroundTaskRegistration task = RegisterBackgroundTask(entryPoint, taskName, taskTrigger, exampleCondition);
计时器后台任务创建方式还是与SystemTrigger十分相似。
创建时间触发器
创建新的 TimeTrigger。第二个参数 OneShot指定后台任务是运行一次还是保持周期性运行。如果 OneShot被设置为 true,则第一个参数 (FreshnessTime) 会指定在计划后台任务之前需等待的分钟数。如果 OneShot被设置为 false,则FreshnessTime会指定后台任务的运行频率。
Windows 8 具有以 15 分钟间隔运行后台任务的内置计时器。
如果 FreshnessTime设置为 15 分钟并且 OneShot为 true,则任务将从其注册之时起 0 至 15 分钟内运行一次该任务。
如果 FreshnessTime设置为 15 分钟并且 OneShot为 false,则任务将从其注册之时起 0 至 15 分钟内每隔 15 分钟运行一次该任务。
注意 如果 FreshnessTime设置为少于 15 分钟,则在尝试注册后台任务时将引发异常。
TimeTrigger hourlyTrigger = new TimeTrigger(60, false); SystemCondition userCondition = new SystemCondition(SystemConditionType.UserPresent); BackgroundExecutionManager.RequestAccessAsync(); string entryPoint =“Tasks.ExampleBackgroundTaskClass”; string taskName =“Example hourly background task”; BackgroundTaskRegistration task = RegisterBackgroundTask(entryPoint, taskName, hourlyTrigger, userCondition);
其他触发器参考(这里要注意的是使用限额):
或者你的应用对后台实时性要求非常高 可以考虑下 :
MSDN 说的非常拗口,我把它翻译成人话说说,
PushNotificationTrigger 实际上就是在应用受到推送的时候才执行的后台代理,用来扩展推送对应用自身功能。
ControlChannelTrigger 是针对与一些应用无法使用 WNS 推送服务的一种解决方案,或者有关于隐私或消息服务级别协议 (SLA) 的问题时,通常需要此类。
详情参考: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj662741.aspx