在手机上,使用后台,不像电脑上那么随意,准确地讲嘛,在移动平台上,后台任务都有严格的限制。至于说为什么会有这么多限制,我估计初衷很明显——保证系统的性能不受某个或某几个应用的负面影响;另外就是出于安全性考虑。

毕竟手机设备不同于电脑,一旦后台程序泛滥成灾,是很难进行管理的,要防止这些不可预知的事件,只能从源头上杜绝。因此,当初在RT应用上就是:允许后台任务,但你得按规矩做人。

无规矩不成方圆,没有限制就会乱象横生,无法控制,现在某手机系统就深陷这一问题无法自拨,WP没有必要重蹈这一覆辙。

好,前面废话了那么多,就是要告诉大家,在开发的时候一定要想清楚,到底该不该使用后台任务,使用后台任务的话,一定要自己亲测一下,是否会明显消耗电量,是否会产生庞大的网络流量。大家一定要养成一个好习惯——以做流氓程序为耻。说到这里,不得不鄙视一下国内的某些公司。

既然后台任务是有限制的,那么,官方是通过什么方式来限制的呢?

触发器:后台任务必须通过触发器来执行。这个触发器,可以理解为类似生物的条件反射。清单文件给出的触发类型有:后台音频、计时器、系统维护等。记得前面我写过博客,弄了一个在点亮屏幕时播放音乐,虽然这种做法不尽合理,但也作为一种参考吧。那个示例就是通过系统触发器中的UserPresent类型触发的,就是当用户把手机屏幕点亮这一行为发生后就会执行后台任务。

比如,比较常用的还有计时器,这个应该会用得较多,比如每隔一段时间提取一批新闻列表等,如每30分钟就执行一次。当然这计时器是有限制的,常规要求是至少15分钟。不然的话,一些人品不端正的开发者弄个每分钟触发一次,那还得了,如果它是提取广告的话,那不断地弹广告就会把用户弹傻了。大家千万别干这种事,你要干这种事,我只能说你太没出息。

凡是实现了IBackgroundTrigger接口的都是触发器,常以“Trigger”结尾,并不是所有触发器都能用,有些是需要申请的,比如ChatMessageNotificationTrigger,这也是防止恶意程序的做法。

执行条件:这个主要由SystemCondition类表示。执行条件与触发器不同,触发器是表明在什么事实发生后执行后台任务,而执行条件是在什么情况下才能执行后台任务。你听起来好像意思接近,实际上是不同的。比如,如果你的后台任务需要从网络上获取数据,而且触发器为每25分钟一次的计时器,于是在注册后台任务时,你可以考虑增加一个执行条件:在有网络连接的前提下执行。虽然计时器的时间到了,但正好这个时候,由于用户的手机卡欠下4G流量费8622000元,被停机了,没法上网,那么系统检测到不存在有效的网络连接,就不执行后台任务了(可以考虑用WiFi)。

如何使用后台任务

前面扯了一堆臊话,主要是让朋友们对后台任务有个大致的了解,现在向大家介绍如何用后台。

代表后台任务的代码通常应该写在一个独立的组件中,这样做也比较科学的,有些朋友在开发程序时,喜欢把所有功能都塞到一个主程序里,许多人在开发桌面程序时就喜欢这样,把所有功能都塞进一个exe中,连.dll都不舍得多用一个,我不喜欢这样做的,一般我是一个功能模板用一个独立的.dll,至于.exe用来放UI或者一些核心处理。

因此,第一步是向解决方案中添加一个Windows运行时组件,看清楚,是运行时组件,最后会生成.wimd文件,如果是类库就会生成.dll文件。后台任务都应写在Windows运行时组件中。这个应该会了吧,就是在“解决方案资源管理器”中新建项目,然后选Windows运行时组件,输入项目名字就可以了,如果你不会这个,我只能告诉你:基础不扎实,举步艰难。

然后在新建的运行时组件中定义一个类,一定要是public的,不要问我为什么(请复习程序集的可访问性),这个类要实现IBackgroundTask接口,表示它用于执行后台任务。

    public sealed class DemoTask : IBackgroundTask
{
public void Run ( IBackgroundTaskInstance taskInstance )
{ }
}

重点是实现Run方法,当后台任务执行时,就是调用这个方法的,你的后台任务要做什么就写在Run里面。
注意到有个IBackgroundTaskInstance类型的参数,是个接口,我们不用管它哪个类实现,这个在系统调用时会自动赋值,只关心它有哪些成员即可。

一定要明白GetDeferral方法的作用,它可以返回一个BackgroundTaskDeferral对象,这个对象的作用,说简单一点就是用来拖延时间的,就是拖延后台任务的时间,当你觉得后台任务已经完成了,就调用用BackgroundTaskDeferral的Complete方法,告诉系统:任务做完了,系统收到报告后,就可以清理该任务了。

现在我们来实现一下这个任务。

        public void Run ( IBackgroundTaskInstance taskInstance )
{
var def = taskInstance.GetDeferral();
// 获取XML模板
XmlDocument docx = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
// 修改XML
var eles = docx.GetElementsByTagName("text");
if (eles.Count < )
{
def.Complete();
return;
}
XmlElement text01 = (XmlElement)eles[];
text01.AppendChild(docx.CreateTextNode("示例"));
XmlElement text02 = (XmlElement)eles[];
text02.AppendChild(docx.CreateTextNode("后台任务执行了。")); // 产生Toast通知
ToastNotification notification = new ToastNotification(docx);
// 显示通知
ToastNotificationManager.CreateToastNotifier().Show(notification); // 报告任务完成
def.Complete();
}

这个任务,不复杂,就是向用户发一条Toast通知。

好,后台任务已经写好了,现在要在主项目中对它进行引用,一定不要忘了,只有引用了上面写的Windows运行时组件才能访问它,这和以前.net项目一样。

这个后台任务,我打算让它每40分钟执行一次,所以触发器应选用TimeTrigger。下面先简单设计一下UI。

    <StackPanel>
<Button Content="注册后台任务" Click="开始注册"/>
<Button Content="取消后台任务" Click="取消注册"/>
<TextBlock x:Name="tb" FontSize="" TextWrapping="Wrap"/>
</StackPanel>

界面简单,你看得懂的,其实事件处理的方法名是可以用中文的,在VS里面,类型名、命名空间名、成员名、参数名都可以用中文的,如果你不喜欢英文名字,可以用中文。

通常,注册后台任务需要准备以下证件:

1、个人身份证,即后台任务的名字,这个名字必须唯一,不能与现有的任务重复。

2、户口本。即入口点,指的是我们前面在Windows运行时组件中定义的那个类的类名,就是那个实现IBackgroundTask接口以及Run方法的类。

为了在输入代码时不容易输入,最好先将这些内容声明为常量。

        /// <summary>
/// 任务的唯一名称
/// </summary>
const string TASK_NAME = "haha_task";
/// <summary>
/// 入口点
/// </summary>
const string ENTRY_POINT = "BackTest.DemoTask";

注意,入口点的名字是要包含命名空间名字的。

好,前期手续基本办完,现在可以正式注册了。下面代码分别用于注册和取消注册后台任务。

        private async void 开始注册 ( object sender, RoutedEventArgs e )
{
var res = await BackgroundExecutionManager.RequestAccessAsync();
if (res != BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity)
return; // 注册
BackgroundTaskBuilder bd = new BackgroundTaskBuilder();
bd.Name = TASK_NAME; //任务名
bd.TaskEntryPoint = ENTRY_POINT; //入口点
// 设置触发器为计时器
bd.SetTrigger(new TimeTrigger(, false));
try
{
BackgroundTaskRegistration reg = bd.Register();
// 注册成功,显示结果
tb.Text = string.Format("任务名:{0}\n任务ID:{1}", reg.Name, reg.TaskId);
}
catch (Exception ex)
{
tb.Text = ex.Message;
}
} private void 取消注册 ( object sender, RoutedEventArgs e )
{
// 先查找一下是否已经注册了任务
var task = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(t => t.Name == TASK_NAME);
if (task != null)
{
// 取消
task.Unregister(true);
}
}

1、在注册之前一定要调用BackgroundExecutionManager.RequestAccessAsync方法,是然不会弹出任何提示,但不要忘了,不调用是不能注册的。

2、BackgroundTaskBuilder类,顾名思义,就是用来注册后台任务的。

3、TimeTrigger触发器的构造函数的第二个参数如果为true,那后台任务只运行一次,这里我希望它每40分钟运行一次,所以为false。

现在,离成果不远了,但是还有一步很关键,那就是配置清单文件。

打开Package.appxmanifest文件,切换到“声明”选项页,在可用的声明列表中选“后台任务”,然后点击添加按钮。

在右边的页面中,按实际情况勾选,我这个例子是计时的,所以选计时器,然后在下面再填写一下入口点,这个入口点和注册后台任务时用的入口点是一样的,可以直接从刚才的代码中复制过来。

因为本例要用到Toast通知,所以要让应用支持Toast。切换到“应用程序”选项卡,在下面有关通知设置的地方,将支持Toast通知设置为“是”。

最后,保存并关闭清单文件。

如何调试后台任务

像我这个例子,要等40分钟才执行的,难道我在干等不成? 非也,我们不用在那里苦等40分钟,VS会帮助我们进行调试的。

首先,运行应用程序,然后点页面上的注册按钮,确保后台任务已经成功注册。

然后回到VS,在“调试位置”工具上,点击“生命周期事件”按钮右边的下拉箭头,从下拉菜单中你会看到有后台任务的名字。如下图。

如果看不到,你可以稍等一下,如果一直不出现,你可以重复上面的步骤。只要后台任务注册成功的,肯定会显示的(后台音频和推送通知除外)。

所以,现在你调试后台任务就很方便,直从“调试位置”工具栏的下拉菜单中选中后台任务,后台任务就会执行了。

OK,相信通过这篇破文,初学者能够初步认识后台任务。

示例源码:http://files.cnblogs.com/tcjiaan/SampleAppBackTask.zip

【WP8.1开发】认识后台任务的更多相关文章

  1. C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!!

    原文:C# Windows Phone 8 WP8 高级开发,制作不循环 Pivot ,图片(Gallery)导览不求人! 内附图文教学!! 一般我们在开发Winodws Phone APP 的时候往 ...

  2. WP8.1开发:简单天气预报应用(转)

    今天小梦给大家分享一个简单的天气预报应用源码:调用的是百度API.整个应用都没有什么难点.只是一个简单的网络请求和json数据处理.在WP8.1有小娜的情况下,天气预报应用还有意义吗?我认为还是有点意 ...

  3. WP8.1开发:简单的天气预报应用

    今天小梦给大家分享一个简单的天气预报应用源码:调用的是百度API.整个应用都没有什么难点.只是一个简单的网络请求和json数据处理.在WP8.1有小娜的情况下,天气预报应用还有意义吗?我认为还是有点意 ...

  4. WP8.1开发:后台任务详解(求推荐)

    小梦今天给大家分享一下windows phone 8.1中的后台任务如何实现,许多应用都会用到后台任务,所以我们必须得掌握. 新建后台任务类: 首先我们先新建一个windows phone 8.1空白 ...

  5. 1_1准备工作[wp8特色开发与编程技巧]

    1准备工作 大家好,我是徐文康,今天我要开始带大家玩转windowsphone8 app的开发 在这一套视频中,我将带大家从零开始学习编程.在互联网时代熟悉编程是非常有必要的.差异化竞争将变成趋势,那 ...

  6. 质问微软 WP8.1开发HTTPS 真费劲

    本人用C#多年,WPF2年,一直想做点应用为WP生态贡献一点力量,最近终于有机会接触了 家里的本子是2年前的低压I3,不支持虚拟化,一直没有真机.最近同事妈妈换下来一个820给我拿来做开发用,非常感谢 ...

  7. (wp8.1开发)触摸键从推出变返回

    ---恢复内容开始--- 今天开发wp8.1,遇到这样一个问题,从第一个页面跳到第二个页面,在第二个页面按返回,结果程序退出了.原来是系统把返回键定义成退出了. 解决办法: 在第一个页面加入如下代码 ...

  8. wp8.1 Study15:后台任务

    一.介绍 1.多任务处理 什么是多任务处理?它意味着当App被挂起时,它仍然可以完成一些开发者设定的任务,比如更新tiles和toasts.预定toast和提醒.后台任务等. 2.后台任务 App可以 ...

  9. 4_1 wp8数据绑定与独立存储空间[wp8特色开发与编程技巧]

    Wp8数据绑定与独立存储空间 数据绑定为基于 Silverlight 的应用程序提供了一种显示数据并与数据进行交互的简便方法. 数据的显示方式独立于数据的管理. UI 和数据对象之间的连接或绑定使数据 ...

随机推荐

  1. [UCSD白板题] Huge Fibonacci Number modulo m

    Problem Introduction The Fibonacci numbers are defined as follows: \(F_0=0\), \(F_1=1\),and \(F_i=F_ ...

  2. opencv在ios上的开发教程

    http://docs.opencv.org/doc/tutorials/ios/hello/hello.html  openCV 2.4.3 iOS background_segm.hpp 'lis ...

  3. PL/SQL通过存储过程为相同数据添加序号

    在Oracle数据库中存有一串数据(Ori_Seq),数据包含不等量重复: 为方便查看与管理,现希望添加一字段(New_Seq),在原有数据的末尾为其添加一串序号,相同数据序号从小到大排列,序号长度为 ...

  4. android studio导入jar的两种方式

    一.第一种是打开工程所在Project Structure,然后选择Dependencies,点击那个加号选择File Dependency ,然后再Libs文件夹中选择要导入的jar包 1. 2. ...

  5. Android--网络请求

    1.Android 上发送HTTP 请求的方式一般有两种,HttpURLConnection 和 HttpClient: 2.HttpURLConnection 的用法: 1)获取 HttpURLCo ...

  6. 纯练手设置ip地址脚本

    #!/bin/bash IFO() { read -p "Configure $line Network card ( 'yes'or'no' )?" CDN </dev/t ...

  7. SecureCRT使用sz和rz命令进行文件的上传和下载

    SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. ...

  8. PHP学习第一天笔记——php的基本语法

    1.php嵌入到html中的方式 (1) <?php.....?> 标准风格(推荐) (2)<script language="php">......< ...

  9. crtmpserver系列(二):搭建简易流媒体直播系统

    crtmpserver简介 我们在第一章的时候已经简要说明了crtmpserver,crtmpserver是一个由C++语言编写的开源的RTMP流媒体服务器,与其对应的商业产品自然是Adobe公司的F ...

  10. angularjs 时间格式化

    本地化日期格式化: ({{ today | date:'medium' }})Nov 19, 2015 3:57:48 PM ({{ today | date:'short' }})11/19/15 ...