Windows 8.1 应用开发后台任务概述(Windows XAML)

说到后台任务,这是在和许多 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 注册任务时传入的参数一致(为了声明后台代理的权限以及要运行代理逻辑的命名空间)

image

对于后台任务代码实现部分简单的说分为两个部分:

 第一部分:运行的逻辑体本身(业务逻辑部分)你需要创建一个后台任务类(具体步骤借用MSDN原话)

你可以通过编写用于实现 IBackgroundTask 接口的类来在后台运行代码。在使用诸如 SystemTriggerMaintenanceTrigger 等触发器触发特定事件时,将运行该代码。

以下步骤介绍如何编写实现 IBackgroundTask 接口的一个新类。开始之前,在解决方案中为后台任务创建一个新项目。为后台任务添加一个新的空类,并导入Windows.ApplicationModel.Background 命名空间。

  • 为后台任务创建一个新项目并将其添加到你的解决方案。为此,请右键单击你的解决方案并选择“添加”->“新建项目”。然后选择 Windows 运行时组件项目类型,命名项目,并单击“确定”。

  • 从 Windows 应用商店应用引用后台任务项目。首先,右键单击你的 Windows 应用商店应用项目并选择“属性,然后转到“常见属性”并单击“添加新参考”,选中后台任务项目旁边的复选框,然后单击两个对话框中的“确定”。

  • 创建一个实现 IBackgroundTask 接口的新类。Run 方法是在触发指定的事件时必须调用的输入点;每个后台任务中都需要该方法。

    注意  后台任务类本身(以及后台任务项目中的所有其他类)必须是属于 sealedpublic 类。

 //
// ExampleBackgroundTask.cs
//

using Windows.ApplicationModel.Background;

namespace Tasks
{
    public sealed class ExampleBackgroundTask : IBackgroundTask
    {
        public void 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

image

实际 8.1 SDK 中枚举选项会多一些。

image

为了我们后台代理执行的有效性 例如:只有在机器联网的情况下执行后台代理,windows移动平台的后台代理 为我们提供了 后台任务的执行条件选择的机会。由 SystemConditionType 枚举表示,在Win8.1 SDK 中实际会比截图中的选项更多一些

image

image

这里有一个注册后台代理的代码给大家参考下(可以直接使用。 注:这里的 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.
//
public static 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 触发器的方法体的方法上面事件触发器的形式是一致的。这个触发器的作用顾名思义 就是当应用更新完成以后激发。

image

 

除了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**](https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/windows.applicationmodel.background.timetrigger.aspx)。第二个参数 *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);

 

其他触发器参考(这里要注意的是使用限额):

 

image

 

或者你的应用对后台实时性要求非常高 可以考虑下 :

image

MSDN 说的非常拗口,我把它翻译成人话说说,

PushNotificationTrigger 实际上就是在应用受到推送的时候才执行的后台代理,用来扩展推送对应用自身功能。

ControlChannelTrigger  是针对与一些应用无法使用 WNS 推送服务的一种解决方案,或者有关于隐私或消息服务级别协议 (SLA) 的问题时,通常需要此类。

详情参考: https://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj662741.aspx