ApplicationData 划分为三大类数据,我们将这三个类别称为位置:本地、漫游和临时
了解用户数据和应用程序数据之间的差别。用户数据是指用户在使用应用程序过程中创建和管理的数据,例如用户的文档、音乐、视频和图片。也可以是用户十分珍视或者要在不同应用程序之间共享的任何内容。这类数据应该存储在其中一个 KnownFolder 库中,或使用 SkyDrive API 进行漫游。密码应始终使用 PasswordVault 进行存储和漫游。本博文所涵盖的范围是那些由应用程序创建和管理的数据,例如应用程序的设置、首选项和状态等。下表中总结了用户数据和应用程序数据之间的区别,以及如何漫游不同的数据。
用户数据 | 应用程序数据 |
可由多个应用程序使用 | 仅对创建该数据的应用程序有意义 |
文档、音乐、图片和导出的数据 | 设置、首选项、环境和应用程序状态 |
使用 SkyDrive 存储在云端 | 使用 ApplicationData 漫游 |
打造只需配置一次即可随处使用的体验
我们先从一个简单地配置一次即可随处使用的体验开始。假设我有这样一个应用程序,它是简单的 RSS 阅读器,使用户可以用于从一系列源中读取项目。查看特定的源时,应用程序会在每页上显示一定数量的项目。我有一个可供用户配置的设置,名为 ItemsPerPage,它控制每页上显示多少个源项目。我希望实现的效果是:如果用户在一台 PC 上设置此设置,它会漫游到安装了相同应用的其他 PC 上。在 ApplicationData 类中,有一个 RoamingSettings 属性,要漫游设置十分简单,只需要将该设置作为一个值写入 RoamingSettings 中即可。
JS:
Windows.Storage.ApplicationData.current.roamingSettings.values[“ItemsPerPage”] = 10
C#:
Windows.Storage.ApplicationData.Current.RoamingSettings.Values[“ItemsPerPage”] = 10;
就是这样!所有同步技术都由 Windows 处理,我不需要再做任何操作,该设置现在就会在安装了我的应用程序的所有用户 PC 之间同步。该设置通常在应用程序“设置”超级按钮中呈现给用户。我强烈建议您在默认情况下漫游所有应用程序设置。有些设置可能是特定于计算机的,不应该保存到漫游位置。
如果您要写入一个文件,而不是一个设置,可以使用应用程序数据中提供的具有相同功能的 RoamingFolder。如果您选择使用文件来漫游数据,请确保在完成写入数据后关闭该文件的所有打开句柄。具有打开句柄的文件无法漫游。
规划漫游配额
如果您在应用程序中使用的都是简单设置,那么上述内容就已经足够满足您的需求了。但如果要漫游收藏夹列表、数据集或更大量的数据,又该如何?最大可以多大?漫游应用程序数据已针对漫游设置和首选项进行优化,并且还有一个面向每个应用程序的存储配额,适用于这些类型的数据。该配额的存在是为了适应系统资源。电池寿命长、系统性能好是 Windows 8 的两个重要特征,而且我们设定的限制可以帮助确保在提供上述漫游体验时,这两项都不会有任何损失。您可以使用 ApplicationData 的 RoamingStorageQuota 属性来获取此配额,该属性在写入时大小为 100 KB。在配额内工作的最佳方式是在设计时规划您的应用程序的数据使用,确保它不会超出配额。
如果超出了 RoamingStorageQuota,会发生什么情况?什么也不会发生!更具体地说,不会漫游任何内容。您的应用程序不会中断,可以继续从漫游位置读取数据和向其中写入数据。但直到漫游位置中的漫游数据总和少于 RoamingStorageQuota,该数据才会同步到云端。
未能恰当规划漫游数据使用的应用程序经常遇到的一个陷阱是,它们会漫游内容,而不是漫游对内容的引用。例如,如果想要漫游一系列收藏的新闻文章,应该漫游文章的标识符或 URL,而不是完整的文章。漫游可用内容的原始数据而不是对这些内容的引用会更快地用尽配额,造成空间浪费。通过漫游内容的标识符而不是实际内容本身可以更充分利用漫游的优势。
规划应用程序时,最好不要使用繁重的数据集。像收藏夹列表这样的开放式数据集应加以限制,以使您的应用程序始终保持在漫游配额范围内。我们还用前面提到的 RSS 源阅读器示例,假设我想要保存 RSS 源的列表,该列表是由用户管理的。实现这一目标的方法是给没有限制的内容加上限制。这需要进行一些估算。假设我想为 RSS 源列表分配 20 KB。为简单起见,我做出一个保守的估计,假设每个 URL 是 80 字节。根据这一估计,我可以把 250 个 URL 塞进 20 KB 中。缩短 URL 可以把所需空间减到更小,但 250 很可能就已经远超我的应用程序所需要的源数量了。我只需要将其限制在该值之内,并将我的源列表写入一个文件,保存在 RoamingFolder 中,就大功告成了。
打造跨不同 PC 的连续体验
您还可以在您的应用程序中添加另一种很酷的漫游体验,那就是跨不同 PC 的连续用户体验!假设某个用户在家中的台式计算机上使用我的阅读器获取源,但她赶着出门搭乘公共汽车。在出门前,她拿起 Windows 8 平板电脑,并打开我的应用程序。我希望为她提供的体验是让她能够从在台式 PC 上停下的地方继续读取源。实现连续体验就是要保存用户执行操作的环境,并进行漫游。
从功能上来讲,这与漫游其他任何设置并无差异,但这种应用场景与大多数设置都有点不同。用户可能会非常快速地导航源,因此该设置可能会频繁改变,而其他设置通常不会出现这种情况。而且,要提供真正令用户满意的体验,关于用户最后执行的操作的数据必须十分准确。为了满足这些客户的需求,我们针对这样的体验创建了一个经过专门设计的唯一设置名称 HighPriority。要使用该设置,只需在 RoamingSettings 的根容器中将您的设置命名为 HighPriority。它的用法与其他设置相似。漫游引擎允许此设置以远快于其他漫游数据的速度漫游,从而使您能够提供用户所需的体验。
要使我的源阅读器具备这样的功能,我只需要漫游源标识符。在应用程序启动时,或当它从挂起状态恢复时,我会检查标识符,并浏览到相应的源。这与我前面的设置非常相似,只是该设置名称为 HighPriority。
JS:
Windows.Storage.ApplicationData.current.roamingSettings.values[“HighPriority”] = currentFeedId;
C#:
Windows.Storage.ApplicationData.Current.RoamingSettings.Values[“HighPriority”] = currentFeedId;
与其他漫游体验相似,Windows 会负责所有复杂的工作,因此您不必担心。使用 HighPriority 的关键在于知道何时读取设置以及何时写入。一般而言,在应用程序启动时或者当它从暂停中恢复时检查 HighPriority,从而使用户无论在当前 PC 还是在其他 PC 上都可以获取他们最后一次使用应用程序时执行的操作。我们会针对用户发起的操作写入 HighPriority,例如导航至新页面或单击链接时。
HighPriority 设置通常是瞬时性的,但可能会因快速写入而受阻,因此不必要的写入只会造成应用程序内性能衰减,而不会改善漫游体验。通常的规则是,使 HighPriority 代表用户执行操作的位置和内容,例如当用户在应用程序中浏览网页或浏览内容时。有些应用程序可能包含快速改变的数据,例如跟踪正在播放的视频内计数器的视频播放器。在每次视频计数器数量增大时都写入 HighPriority 有些小题大做,您可以改为当视频改变状态(例如播放/暂停)时、用户到达一个检查点或当应用程序暂停时更新该设置。
使您的数据保持一致
有些数据紧密相关,应该始终一起漫游。最经典的例子是一个点的坐标。当发生更改时,x 和 y 坐标不能分开单独漫游,否则就可能会破坏数据,产生无效的点。ApplicationData 的漫游单元是设置和文件,因此文件中的所有内容会作为一个单元始终一起漫游,而设置本身就是一个单元。如果您希望多个设置一起漫游(例如坐标),您可以使用 CompositeSettingValue。该类型的设置允许将多个设置归组到单个值,因此始终将作为一个单元一起漫游。
HighPriority 设置也可以是个复合值,使您可以安全地漫游代表您的应用程序当前状态的多段数据。例如,我的源阅读器会按页面将源项目进行分组,以方便阅读。我不希望源 ID 和页面分开单独漫游,因为源的页数可能会不同。我想要执行的操作是使当前的源 ID 和该源中的当前页面一起作为 CompositeSettingValue 漫游,从而使它们始终保持一致。
JS:
var currentFeed = new Windows.Storage.ApplicationDataCompositeValue();
currentFeed.insert(“CurrentFeedId”, currentFeedId);
currentFeed.insert(“CurrentFeedPage”, currentFeedPage);
Windows.Storage.ApplicationData.current.roamingSettings.values[“HighPriority”] = currentFeed;
C#:
Windows.Storage.ApplicationDataCompositeValue currentFeed =
new Windows.Storage.ApplicationDataCompositeValue();
currentFeed.Insert(“CurrentFeedId”, currentFeedId);
currentFeed.Insert(“CurrentFeedPage”, currentFeedPage);
Windows.Storage.ApplicationData.Current.RoamingSettings.Values[“HighPriority”] = currentFeed;
如果一个复合值用作 HighPriority 设置,那么它必须小于 8 KB,才能保留 HighPriority 的优势。超出 8 KB 不会造成错误,但它将像普通设置一样进行漫游。
响应即将发生的漫游变更
还有最后一个部分有关漫游体验的知识您应该了解,那就是 ApplicationData 的 DataChanged 事件。DataChanged 事件是一个单纯的事件,您可以在应用程序数据发生改变时随时发出信号,例如,在用户改变设置时向后台任务发出信号。当云端中的漫游数据导致您的应用程序发生本地更改时,Windows 会自动就此事件向您发出信号。这样,您便可以应对这样的情况:来自另一台 PC 的数据可能已被延迟,然后在用户已经开始使用您的应用程序之后到达。您可以使用此事件来刷新您的数据视图或响应设置更改。有一点很重要,那就是这种体验适用于用户每次使用一台 PC 并在不同 PC 之间切换的情况,因此您不应将 DataChanged 事件用作不同 PC 之间的实时通信机制。