动态磁贴(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的CreateTileUpdaterForApplicationCreateTileUpdaterForSecondaryTile 方法来获取。如:

 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】后台任务与动态磁贴的更多相关文章

  1. win10 uwp 活动磁贴

    本文翻译:https://mobileprogrammerblog.wordpress.com/2015/12/23/live-tiles-and-notifications-in-universal ...

  2. UWP Windows10开发更新磁贴和动态更新磁贴

    下面将介绍两种方式如何在windows10 uwp开发中如何更新应用磁贴: 实际上windows的磁贴就是用xml实现的,你只需要创建相应格式的xml就可以实现动态磁贴了 一,手动更新磁贴 二,轮询更 ...

  3. Win10 UWP版《芒果TV》v2.4.0直播超女,芒果台综艺一网打尽

    Win10 UWP版<芒果TV>直播超女,芒果台综艺一网打尽 Win10版UWP<芒果TV>自2015年9月登录商店以来,一直在持续更新,积极改进,拥有芒果台视频的独家点播和直 ...

  4. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  5. win10 UWP 序列化

    将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. .NET Framewor ...

  6. win10 uwp 如何开始写 uwp 程序

    本文告诉大家如何创建一个 UWP 程序. 这是一系列的 uwp 入门博客,所以写的很简单 本文来告诉大家如何创建一个简单的程序 安装 VisualStudio 在开始写 UWP 需要安装 Visual ...

  7. win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑

    本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...

  8. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  9. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

随机推荐

  1. Java Reflection

    Java语言的反射机制 1. Java反射的含义:获取应用中正在运行的Java对象. 2. Java反射机制: 在运行的程序中,对于任意的类,都可以知道这个类的属性.方法以及构造函数,对于任意对象都可 ...

  2. python函数动态参数详解

    Python的动态参数: 1,参数前一个"*":在函数中会把传的参数转成一个元组. def func (*args): print(args) func(123,1,2,'a') ...

  3. Myeclipse 安装离线adt的方法 ()

    方法一: 1.下载最新的adt插件ADT-10.0.1.zip (在MyEclipse 10.5 上安装的ADT插件是ADT 20.0.3离线包下载地址: http://dl.cr173.com//s ...

  4. Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系

    转载请包含网址:http://blog.csdn.net/pathuang68/article/details/7351317 一.Surface Surface就是“表面”的意思.在SDK的文档中, ...

  5. android中ColorStateList及StateListDrawable设置Selector

    写过android的代码相信大家对Selector并不陌生吧,下面来看看这段xml文件是如何定义的 <?xml version="1.0" encoding="ut ...

  6. simplexml_load_string 解析xml

    <?php //simplexml_load_string 解析两种类型的xml $res='<?xml version="1.0" encoding="UT ...

  7. .Net Framework运行机制

    首先谈谈.net framework的组成 主要是有两大部分组成:CLR(公共语言运行库)和FCL(Framework类库) CLR的主要功能:和Java虚拟机一样也是一个运行时环境,是一个可由多种编 ...

  8. 利用(Tcmalloc) google-perftools优化Nginx和MySQL性能

    一.安装libunwind wget http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz 本地下载:htt ...

  9. archlinux 安装过程记录

    2014年安装了一次,使用U盘启动安装的,但是当时网络有问题,断断续续,没有做详细记录. 现在到了杭州,重新来一次. 使用U盘安装 下载ISO :http://mirrors.163.com/arch ...

  10. Oracle优化的方法

    想做到数据库优化的高手,不是花几周,几个月就能达到的,这并不是因为数据库优化有多高深,而是因为要做好优化一方面需要有非常好的技术功底,对操作系统.存储硬件网络.数据库原理等方面有比较扎实的基础知识,另 ...