【Win10 UWP】后台任务与动态磁贴
动态磁贴(Live Tile)是WP系统的大亮点之一,一直以来受到广大用户的喜爱。这一讲主要研究如何在UWP应用里通过后台任务添加和使用动态磁贴功能。
从WP7到Win8,再到Win10 UWP,磁贴模板不断进行调整和优化,目前磁贴模板已经发展到第三代,一般称之为“Adaptive Tile Templates”。
在运用UWP动态磁贴之前,请先了解一下自适应磁贴的语法规则。关于自适应磁贴模板的语法规则,请详读这篇文章:http://blogs.msdn.com/b/tiles_and_toasts/archive/2015/06/30/adaptive-tile-templates-schema-and-documentation.aspx
一. 磁贴更新的原理
磁贴的“动态”,在于它能不断地进行更新,展示新的内容。磁贴又可分为主磁贴(即由应用列表Pin到桌面的磁贴)和二级磁贴(即由应用内部通过程序控制Pin到桌面的磁贴)。这两种磁贴都支持小、中、宽和大磁贴4种尺寸。
Windows.UI.Notifications.TileUpdater可以用来管理和修改当前磁贴的内容,从而达到更新磁贴的目的。TileUpdater对象必须通过Windows.UI.Notifications.TileUpdateManager的CreateTileUpdaterForApplication或CreateTileUpdaterForSecondaryTile 方法来获取。如:
- var updater = TileUpdateManager.CreateTileUpdaterForApplication();
- var updater = TileUpdateManager.CreateTileUpdaterForSecondaryTile("appdota2");
然后调用updater的Update方法即可实现对内容的更新。Update方法需要传入一个TileNotification对象:
- //
- // 摘要:
- // 将内容或外观的更改应用于图块。
- //
- // 参数:
- // notification:
- // 为平铺的内容提供新的 XML 定义的对象。
- public void Update(TileNotification notification);
顾名思义,TileNotifiction承载着要进行通知的磁贴模板,磁贴模板实际上就是一个定义好的XML文件。在UWP里,这个磁贴模板就需要按照“Adaptive Tile Templates”的规则来定义。
二.磁贴的更新方式
磁贴更新的方式可以通过程序内部控制,如在后台请求新数据并进行更新,这种方式也就是通过后台任务(Background Task)来实现更新;也可以通过推送通知使磁贴产生变化。我们今天重点讲后台任务的更新磁贴方法。
后台任务更新逻辑:
1.应用首先注册一个后台任务
2.后台任务定期向服务器请求新数据
3.服务器传回新的数据
4.后台任务通过TileUpdater更新磁贴内容
三.实现后台任务更新磁贴
1.后台任务逻辑
创建一个WinRT组件,再创建一个类叫LiveTileTask,并且实现IBackgroundTask接口,必须实现接口的Run方法:
- public sealed class LiveTileTask : IBackgroundTask
- {
- public async void Run(IBackgroundTaskInstance taskInstance)
- {
- var deferral = taskInstance.GetDeferral();
- // TODO: 获取数据,更新磁贴逻辑
- deferral.Complete();
- }
- }
Run方法中必须获取deferral对象,并且执行完成后需要调用deferral对象关闭,因为我们在后台任务中是需要执行异步代码的,所以获取完deferral对象之后,大约有5秒钟的时间可以进行异步操作,超过时间系统就会强制释放deferral对象。这样能保证较好的用户体验,如果异步请求的时间过长,自然会认为执行失败而不会去更新磁贴了。
接下来再Run方法中间位置开始执行请求数据的任务:
- public async void Run(IBackgroundTaskInstance taskInstance)
- {
- var deferral = taskInstance.GetDeferral();
- await GetLatestNews();
- deferral.Complete();
- }
- private IAsyncOperation<string> GetLatestNews()
- {
- try
- {
- return AsyncInfo.Run(token => GetNews());
- }
- catch (Exception)
- {
- // ignored
- }
- return null;
- }
其中GetNews方法即向服务端请求数据,完成后可以开始更新磁贴:
- private async Task<string> GetNews()
- {
- try
- {
- var response = await ApiService.GetHotNewsListAsync();
- if (response?.Data != null)
- {
- var news = response.Data.Take().ToList();
- UpdatePrimaryTile(news);
- UpdateSecondaryTile(news);
- }
- }
- catch (Exception)
- {
- // ignored
- }
- return null;
- }
注意磁贴最多只能更新5个,所以只处理返回数据的前5个。
更新磁贴的方法非常简单:
- private void UpdatePrimaryTile(List<News> news)
- {
- if (news == null || !news.Any())
- {
- return;
- }
- try
- {
- var updater = TileUpdateManager.CreateTileUpdaterForApplication();
- updater.EnableNotificationQueueForWide310x150(true);
- updater.EnableNotificationQueueForSquare150x150(true);
- updater.EnableNotificationQueueForSquare310x310(true);
- updater.EnableNotificationQueue(true);
- updater.Clear();
- foreach (var n in news)
- {
- var doc = new XmlDocument();
- var xml = string.Format(TileTemplateXml, n.Pic, n.Title, n.Desc);
- doc.LoadXml(WebUtility.HtmlDecode(xml), new XmlLoadSettings
- {
- ProhibitDtd = false,
- ValidateOnParse = false,
- ElementContentWhiteSpace = false,
- ResolveExternals = false
- });
- updater.Update(new TileNotification(doc));
- }
- 31 }
- catch (Exception)
- {
- // ignored
- }
- }
我们采用队列的形式允许磁贴逐个更新,还有一个需要注意的地方,服务端返回的数据可能带有转义字符,在加载模板XML的时候必须做一下编码处理,否则可能导致异常而无法更新磁贴。当然其中的TileTemplateXml自己根据自适应磁贴的规则定义即可,举例:
- private const string TileTemplateXml = @"
- <tile branding='name'>
- <visual version='3'>
- <binding template='TileMedium'>
- <image src='{0}' placement='peek'/>
- <text>{1}</text>
- <text hint-style='captionsubtle' hint-wrap='true'>{2}</text>
- </binding>
- <binding template='TileWide'>
- <image src='{0}' placement='peek'/>
- <text>{1}</text>
- <text hint-style='captionsubtle' hint-wrap='true'>{2}</text>
- </binding>
- <binding template='TileLarge'>
- <image src='{0}' placement='peek'/>
- <text>{1}</text>
- <text hint-style='captionsubtle' hint-wrap='true'>{2}</text>
- </binding>
- </visual>
- </tile>";
这个模板实现的效果是如同商店应用的Peek动态更新效果:
Animated | Peek shown | Peek sliding up | Content shown | Peek sliding down |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
2.注册后台任务
注意后台任务必须在前台程序进行触发(Trigger)设置,即所谓的注册后台任务。后台任务将根据触发器是否被触发而执行。
Win8.1的Trigger有SystemTrigger, TimeTrigger, MaintenaceTrigger, DeviceUseTrigger, DeviceServingTrigger, PushNotificationTrigger;
WP8.1的Trigger有CachedFileUpdaterTrigger, DeviceConnectionChangedTrigger, GattCharacteristicNotificationTrigger, RfcommonConnectionTrigger, LocationTrigger;
Win10新增了如下Trigger:AppointmentStoreNotificationTrigger, ContactStoreNotificationTrigger, BluetoothLEAdvertisementWarcherTrigger, BluetoothLEAdvertisementPublisherTrigger, DeviceWatcherTrigger, ActivitySensorTrigger, SensorDataThresholdTrigger, ToastNotificationHistoryChangedTrigger, ToastNotificationActionTrigger, ApplicationTrigger, SocketActivityTrigger。
如果我们要进行周期性的磁贴更新,那么我们可以将用Timer触发器去进行触发,需要在Package.appxmanifest中声明一个后台任务,支持的任务类型勾选计时器,且应用设置中Entry Point设置为LiveTileTask的完整类名。
在前台程序的App.cs或其他地方进行设置:
- private const string LIVETILETASK = "LIVETILETAKS";
- private async void RegisterLiveTileTask()
- {
- var status = await BackgroundExecutionManager.RequestAccessAsync();
- if (status == BackgroundAccessStatus.Unspecified || status == BackgroundAccessStatus.Denied)
- {
- return;
- }
- BackgroundTaskRegistration.AllTasks.ForEach(t =>
- {
- if (t.Value.Name == LIVETILETASK)
- {
- t.Value.Unregister(true);
- }
- });
- var taskBuilder = new BackgroundTaskBuilder
- {
- Name = LIVETILETASK,
- TaskEntryPoint = typeof(LiveTileTask).FullName
- };
- taskBuilder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
- var updater = TileUpdateManager.CreateTileUpdaterForApplication();
- updater.Clear();
- var updater2 = TileUpdateManager.CreateTileUpdaterForSecondaryTile("appdota2");
- updater2.Clear();
- taskBuilder.SetTrigger(new TimeTrigger(60, false));
- taskBuilder.Register();
- }
对于后台任务,还可以设定一定的条件使其触发,如当没有网络的情况下,即使到了时间周期,也不会去触发后台任务。
这样就实行了每个60分钟触发一次后台任务,让后台任务去请求新的数据,并将磁贴已队列的形式循环进行更新。
【Win10 UWP】后台任务与动态磁贴的更多相关文章
- win10 uwp 活动磁贴
本文翻译:https://mobileprogrammerblog.wordpress.com/2015/12/23/live-tiles-and-notifications-in-universal ...
- UWP Windows10开发更新磁贴和动态更新磁贴
下面将介绍两种方式如何在windows10 uwp开发中如何更新应用磁贴: 实际上windows的磁贴就是用xml实现的,你只需要创建相应格式的xml就可以实现动态磁贴了 一,手动更新磁贴 二,轮询更 ...
- Win10 UWP版《芒果TV》v2.4.0直播超女,芒果台综艺一网打尽
Win10 UWP版<芒果TV>直播超女,芒果台综艺一网打尽 Win10版UWP<芒果TV>自2015年9月登录商店以来,一直在持续更新,积极改进,拥有芒果台视频的独家点播和直 ...
- Win10/UWP开发—使用Cortana语音与App后台Service交互
上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...
- win10 UWP 序列化
将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. .NET Framewor ...
- win10 uwp 如何开始写 uwp 程序
本文告诉大家如何创建一个 UWP 程序. 这是一系列的 uwp 入门博客,所以写的很简单 本文来告诉大家如何创建一个简单的程序 安装 VisualStudio 在开始写 UWP 需要安装 Visual ...
- win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑
本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...
- Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
- Win10 UWP开发系列:实现Master/Detail布局
在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...
随机推荐
- 去除inline-block元素间间距,比较靠谱的两种办法
1.使用注释符号 <div><span class="1">1</span></div><!-- --><div& ...
- Centos版Linux 一些常用操作命令
Linux命令收集 1.文件处理命令:ls 功能描述:显示目录文件 命令英文原意:list 命令所在路径:/bin/ls 执行权限:所有用户 语法: ls 选项[-ald] [文件或目录] -a ...
- 全自动ARP实时绑定BAT文件
全自动ARP实时绑定BAT文件 说明一下,这个BVS脚本,它会每六秒钟清除一次ARP缓存.并绑定网关.真正做到了实时防护! 代码如下:请另存为.BAT文件.再运行一下,就可以了 path c:\;c: ...
- ue4 重新生成ide project文件的命令行
有时候换了机器,工程文件没了,通常是在编辑器里有个菜单项可以生成 但是有时编辑器自身都编不过,没法运行 这时需要调试代码,可以用命令行生成相应的工程文件: ../UnrealEngine/Genera ...
- tkinter 在 x window 下的字体设置格式
X Font Descriptors # X Font Descriptors are strings having the following format (the asterisks repre ...
- 长轮询(long polling)
HTTP请求不是持续的连接,你请求一次,服务器响应一次,然后就完了.长轮训是一种利用HTTP模拟持续连接的技巧.具体来说,只要页面载入了,不管你需不需要服务器给你响应信息,你都会给服务器发一个Ajax ...
- 开启Python之路
开始自学Python 环境配置 自己百度去!!! 计算与变量 字符创.列表.元组和字典 简单的画图 使用if和else条件控制语句 循环 使用函数和模块来重用代码 使用类和对象 Python内建函数的 ...
- jquery中的cookie
关于cookie,一直是个很敏感的问题,以前对于cookie的处理,都是用原生的方式处理,创建函数对cookie进行处理,创建,设置以及删除.. function setCookie(key,valu ...
- 验证radio 是否被选中
var radioType=document.getElementsByName("radioType"); var isCheckRadio=false; for(v ...
- 【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles
期望计算的套路: 1.定义:算出所有测试值的和,除以测试次数. 2.定义:算出所有值出现的概率与其乘积之和. 3.用前一步的期望,加上两者的期望距离,递推出来. 题意: 一个树,dfs遍历子树的顺序是 ...