Windows Phone 8.1 - 操作 ApplicationData

Windows Phone 8.1 - 操作 ApplicationData


在 8.1 开始,Silverlight App 中使用的 IsolatedStorage 已不支持(例如:IsolatedStorageSettings.ApplicationSettings)

很多操作的方式将全面改用 StorageFile / StorageFolder,针对可操作的目录与数据设定均有不同。

前几篇介绍了 WP 8.1 的 Lifecycle 之后,接下来该篇要介绍如何操作 App 中的 ApplicationData,

协助在 Lifecycle 各阶段里怎么保存与还原数据。

ApplicationData class

   提供存取 application data store。application data store 包括:文件、设定与目录(local, roaming, temporary);

using Windows.Storage;
 
// 利用 ApplicationData.Current 来取得要操作的对象
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;


重要的属性、方法与事件:

类型 名称 说明
Events DataChanged Occurs when roaming application data is synchronized.
Methods ClearAsync() Removes all application data from the local, roaming, and temporary app data stores.
ClearAsync(ApplicationDataLocality) Removes all application data from the specified app data store.
Member Value Description
Local | local 0 The data resides in the local application data store.
Roaming | roaming 1 The data resides in the roaming application data store.
Temporary | temporary 2 The data resides in the temporary application data store.
LocalCache | localCache 3 The data resides in the local cache for the application data store.
SetVersionAsync Sets the version number of the application data in the app data store.
SignalDataChanged Sends a DataChanged | datachanged event to all registered event handlers.
Properties Current Read-only, Provides access to the app data store associated with the app's app package.
LocalFolder Read-only, Gets the root folder in the local app data store.
LocalSettings Read-only, Gets the application settings container in the local app data store.
RoamingFolder Read-only, Gets the root folder in the roaming app data store.
RoamingSettings Read-only, Gets the application settings container in the roaming app data store.
RoamingStorageQuota Read-only, Gets the maximum size of the data that can be synchronized to the cloud from the roaming app data store.
TemporaryFolder Read-only, Gets the root folder in the temporary app data store.
Version Read-only, Gets the version number of the application data in the app data store.

利用 ApplicationData.Current 取得 instance 其中分成几个可操作的目录与设定:

a. ApplicationData.LocalFolder /  ApplicationData.LocalSettings;

   保存在本机设备上的数据,即使 App 更新之后仍然存在;

b. RoamingFolder /  RoamingSettings;

   保存在此的数据可共享在同一个账号下安装相同 App 的不同设备中;

c. TemporaryFolder;

   可以由系统在任何时候被删除;

上述这些保存体均可以搭配“Version”与“SetVersionAsync”来指定搭配那一个 App 的版本要合并或移动既有的数据。

其概念则是:

1. ApplicationData 默认版为 0;

2. 如果升级之后,想要更动 ApplicationData 的版本为  1 时,则要设定 SetVersionAsync ,并给于处理的 Handler,如下:

private async void VersionCheck()
{
    // 取得目前的版本
    var version = ApplicationData.Current.Version;
 
    // 比对版本与预期的版本是否一致,如果不一样,代表是升级的 App,则进行注册的 ApplicationDataSetVersionHandler
    if (version != 1)
    {
        await ApplicationData.Current.SetVersionAsync(1, ApplicationDataSetVersionHandler);
    }
}
 
void ApplicationDataSetVersionHandler(SetVersionRequest e)
{
    // 撰写需要做数据更动或格式转换的逻辑
}


3. 这样一来,下一个版本(可能是 2)就以相同的方式去撰写升级的逻辑在对应的处理 handler 即可。

以下针对这几个部分进行说明。

》Local app data

A. ApplicationData.LocalFolder

       代表 App 可操作本地保存区的 root folder。取得后为 StorageFolder。可透过 protocol 的方式来取得连接 local store 内的数据:

“"ms-appdata:///local/"”,例如:“”。

如果需要取得 App 安装的目录可借由:“Windows.ApplicationModel.Package.Current.InstalledLocation”。

可发现,ApplicationData 被归类在 Windows.Storage 下,而安装目录是放在 Windows.ApplicationModel 下,二者是不同的。

透过下方的范例说明如何操作:

private async void btnWriteLocalFolder_Click(object sender, RoutedEventArgs e)
{
    StorageFolder localFolder = ApplicationData.Current.LocalFolder;
    
    // 建立一个文件,设定 CreationCollisionOption 如果既有文件就覆写
    StorageFile sampleFile = await localFolder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);
    
    String content = "sample data, write to local folder.";
    
    // 利用 FileIO.WriteTextAsync 将内容写入
    await FileIO.WriteTextAsync(sampleFile, content);
}
 
private async void ReadLocalFolderFile()
{
    try
    {
        StorageFolder localFolder = ApplicationData.Current.LocalFolder;
        StorageFile sampleFile = await localFolder.GetFileAsync("sample.txt");
        // 利用 FileIO.ReadTextAsync 取得内容
        String content = await FileIO.ReadTextAsync(sampleFile);
    }
    catch (Exception)
    {
        // 文件不存在
    }
}


上述利用了 StorageFolder 的 Windows.Storage.StorageFolder.CreateFileAsync | createFileAsync 建立文件,

其中设定了 CreationCollisionOption enumeration 值让在建立文件时如遇到文件已存在就覆写 (ReplaceExisting),

利用 Windows.Storage.FileIO.WriteTextAsync | writeTextAsync 将内容写入,搭配 Windows.Storage.FileIO.ReadTextAsync | readTextAsync 取回内容;

Windows.Storage.FileIO

    提供操作(Read / Write) IStorageFile 类型对象的方法。常用的方法如下:

Method Description
ReadBufferAsync Reads the contents of the specified file and returns a buffer.
ReadTextAsync(IStorageFile) Reads the contents of the specified file and returns text.
WriteBufferAsync Writes data from a buffer to the specified file.
WriteBytesAsync Writes an array of bytes of data to the specified file.
WriteTextAsync(IStorageFile, String) Writes text to the specified file.

更多详细说明可以参考

Windows.Storage.FileIO  简化了过去在操作 StorageFile 需要花时间建立 Stream、转换 DataReader / DataWriter …等,让整个程序撰写更加简易。

 

[注意]

a. 在 Windows Store App 里面可以请求 Windows indexes 为 local store 中的数据建立索引,方法:

   1) 先在 Local Folder 下先建立一个“Indexed 目录”;

   2) 将需要被建立索引的文件放在“Indexed 目录”;

   3) Windows indexes 将会把 “Indexed 目录”下的文件与子目录下的文件取得并建立对应的 metadata;

 

  

B. ApplicationData.LocalSettings

        取得 local app data store 中的 application settings container。LocalSettings 是 ApplicationDataContainer。

透过 ApplicationDataContainer.Values | values 取得 localsettings container 中的设定值。 而这个 Values 是 ApplicationDataContainerSettings ,

该内容采用 IDictionary 建立,所以数据是放在这里。ApplicationDataContainer 它只是个容器,但 容器里还可以子容器喔。

由于该设定的组合非常特别,将花一点解释操作 LocalSettings 需要了解的类与作法。

ApplicationDataContainer

   代表应用程序设定的容器。此类的属性与方法支持创建、 删除、枚举和浏览容器层次结构。

该类是非常特别的,因为过去操作的“IsolatedStorageSettings.ApplicationSettings”只是一个单纯 Key/Value 的容器,

但 ApplicationDataContainer 还可以建立子容器来建立需要的数据。透过下列常用的方法与属性来说明:

类型 名称 说明
Method CreateContainer 在目前 settings container 开启或建立指定的 settings container。
在建立或开启 containers 有一个额外枚举参数:ApplicationDataCreateDisposition 需要注意。

‧ApplicationDataCreateDisposition:
   指定 application data containers 建立的选项。有二个枚举值:
  
Member Value Description
Always |always 0 永远启用该容器,如果容器不存在则自动建立。
Existing |existing 1 只有在容器存在时才启用该容器。
DeleteContainer 删除指定的 settings container,它的 subcontainers、application settings 将全部被删除。
Property Containers Read-only,取得目前 application settings container 下的 child application settings containers。
Locality Read-only,取得目前 settings container 关联于 app data store 代表的类型,例如:local 或 roaming。
Name Read-only,取得目前 settings container 的名称。
Values Read-only,取得目前 settings container 的 settings (ApplicationDataContainerSettings)。

范例程序:

private void btnAddNewContainer_Click(object sender, RoutedEventArgs e)
{
    ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
    // 设定新的 container 如果不存在就自动建立
    ApplicationDataContainer newContainer = localSettings.CreateContainer(
                                    "newContainer", ApplicationDataCreateDisposition.Always);
    if (newContainer.Values.ContainsKey("key1"))
    {
        newContainer.Values["key1"] = "Second Key1";
    }
    else
    {
        newContainer.Values.Add("key1", "First Key1");
    }
 
    String value = newContainer.Values["key1"].ToString();
 
    // 删除 container
    localSettings.DeleteContainer("newContainer");
}


ApplicationDataContainerSettings 

   提供存取 settings container中的设定值。所以 LocalSettings | localSettings 属性得到的是 ApplicationDataContainer 对象,

透过 ApplicationDataContainerSettings 来操作,如下程序范例:

var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
 
// Create a simple setting
 
localSettings.Values["exampleSetting"] = "Hello Windows";
 
// Read data from a simple setting
 
Object value = localSettings.Values["exampleSetting"];
 
if (!value)
{
    // No data
}
else
{
    // Access data in value
}
 
// Delete a simple setting
 
localSettings.Values.Remove("exampleSetting");


[注意]

a. ApplicationDataContainerSettings 设定的 setting name 最长 255 符

b. 每个 setting value 最大 8K bytes,每个复合型 setting value 最大 64K bytes

c. 注意可放入的数据类型:Windows Runtime base data types;

ApplicationDataCompositeValue

   Represents related app settings that must be serialized and deserialized atomically. 该类实践 IDictionary 界面,

属于集合性对象,在操作  ApplicationDataContainerSettings 时,可以新增一个新的 setting 用类型的对象来保存以扩充内容(最大 64K bytes)。

该对象被保存时会自动序列化里面的内容,取出去会再反序列化回来,搭配 Key/Value 的方式来操作。

如果 Value 是给予自定义的类要记得声明需要或不可以被序列化的属性,以免出现 Exception。

操作方式如下:

private void btnAddDataLocalSetting_Click(object sender, RoutedEventArgs e)
{
    ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
    // 建立一个 ApplicationDataCompositeValue  对象
    ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();
    composite.Add("name", "pou");
    composite.Add("age", "90");
    if (localSettings.Values.ContainsKey("com1"))
    {
        localSettings.Values["com1"] = composite;
    }
    else
    {
        localSettings.Values.Add("com1", composite);
    }
    localSettings.Values.Remove("com1");
}


》Roaming app data

   在介绍 Roaming Folder 与 Roaming Settings 前,先来了解一下 Roaming data 的用途:

在 App 里使用 Roaming data (文件或设定),用户可以简单地保留 App data,并且同步至不同的设备之中”。

如果用户安装您的 App 在第二台设备以上,系统会自动将 app data 进行同步,减少用户在安装 App 后需要额外设定的工作,

但前提是您的 App 本身也要处理 Roaming data 的变动与事件。

有了 Roaming 同步多设备中 App 的数据,用户就可以在手机还没有玩完的 game 换到 PC 又可以继续接着,或是任务继续延续。

要达到这样的功能,需要几个条件:

1. 同一个 App;

   =>Windows Store App 与 Windows Phone App 需要在 Dev center 注册相同的名称,这样才能同步 roaming data,

       可参考

2. 同一个 Microsoft Account 所购买;

3. 同步的设备为 Windows Store 与 Windows Phone 的 App;

Windows 在支持 roaming data 有一些规范,在保存数据至该目录或设定时要特别注意:

1. 文件与目录的命名不可以有前导空格 (leading whitespace);

2. 限制每一个 App 可以被 Roaming 的大小 (借由 ApplicationData.RoamingStorageQuota | roamingStorageQuota 来得知);

   =>如果 App 的用量超过这个限制,将不会再有数据会被复制到云端,需等到 App 的总 roamed app data 低于限制,才会再次启动

       尤于这样,要做为 roamed app data 的类型最好是一些 user preferences、links、small data files

通常 App 不会希望自己的 app data 被 App 以外的事情来改变。但是 roaming app data 可能随时被改变,所以需要注册 ApplicationData

DataChanged | datachanged 事件,在每次 roaming app data 改变时,同步自己 app 中的对应数据。

如果 App 已安装再透过用户更新了新的版本,那 App 中的 app data 会被复制到 cloud。

系统不会更新到其他设备,需等到使用者更 新 App ,以及这些设备上的 App 上的 app data。

至于复制到云端的 roaming app data (RoamingFolder)会被保存多久呢?目前是 30 天(time interval)。但有可能随着政策而改变。

roaming data 提供 App 有能力在云端保存的有限期间内将数据同步至不同的设备中。

如果用户超过有限时间都没有再回到 App,那云端保存的数据将会被删除

如果用户移除了 App,云端数据不会自动移除,等到有限期间到达才会自动移除,所以这之间用户重新安装仍可以取得数据。

同步的时机点呢?系统处理 roaming app data 不保证立即同步。使用者在离线使用 App 或网络连线速度不够时,可能就会延迟。

注意,如果需要高优先级的同步,希望能够经常性同步的话,可以透过 RoamingSettings 增加一个命名为“HighPriority”的

设定它可以是复合的(composite)设定值,不过大小只有 8KB。如果该设定值超过了 8 KB,其系统不强制执行限制空间

更多使用 roaming app data 的说明可参考

A. RoamingFolder

    取得 roaming app data store 中的根目录。透过“ms-appdata:///roaming/”protocol 来操作文件或目录。

操作方式:

private async void HandleRoamingFolder()
{
    StorageFolder roamingFolder = ApplicationData.Current.RoamingFolder;
 
    // 单位:KB
    ulong maxSize = ApplicationData.Current.RoamingStorageQuota;
 
    // 建立一个文件,设定 CreationCollisionOption 如果既有文件就覆写
    StorageFile roamingFile = await roamingFolder.CreateFileAsync("roamingFile.txt", CreationCollisionOption.ReplaceExisting);
 
    String content = "Roaming data, write to Roaming folder.";
 
    // 利用 FileIO.WriteTextAsync 将内容写入
    await FileIO.WriteTextAsync(roamingFile, content);
}
 
async Task ReadTimestamp()
{
    StorageFolder roamingFolder = ApplicationData.Current.RoamingFolder;
    try
    {
        StorageFile roamingFile = await roamingFolder.GetFileAsync("roamingFile.txt");
        String content = await FileIO.ReadTextAsync(roamingFile);
    }
    catch (Exception)
    {
        // 文件不存在
    }
}


注册 DataChanged | datachanged 事件:

public App()
{
   this.InitializeComponent();
   this.Suspending += this.OnSuspending;            
 
   // 注册要处理 Back Button 的事件逻辑。
   Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
 
   this.Resuming += App_Resuming;
   ApplicationData.Current.DataChanged += Current_DataChanged;
}
 
void Current_DataChanged(ApplicationData sender, object args)
{
   // 从 sender 中取得更新的数据;            
}


B. RoamingSettings

    取得 roaming app data store 中的 application settings containers。它与 LocalSettings 的使用完全相同,本身也是一个 ApplicationDataContainer。

程序范例:

private void HandleRoamingSettings()
{
    ApplicationDataContainer roamingSettings = ApplicationData.Current.RoamingSettings;
    // 设定新的 container 如果不存在就自动建立
    ApplicationDataContainer newContainer = roamingSettings.CreateContainer(
                                    "newContainer", ApplicationDataCreateDisposition.Always);
    if (newContainer.Values.ContainsKey("key1"))
    {
        newContainer.Values["key1"] = "Second Key1";
    }
    else
    {
        newContainer.Values.Add("key1", "First Key1");
    }
 
    String value = newContainer.Values["key1"].ToString();
 
    // 删除 container
    roamingSettings.DeleteContainer("newContainer");
}


》Temporary app data

   Temporary app data 就像是 cache。它的文件不会被 roam,而且可能随时被清除。清除可能来自:

(1) 系统自动清除 (System Maintenance task);

(2) 用户手动透过工作清除 (Disk Cleanup);

所以通常被用来保存临时计算用的文件或数据,用完即丢的目的。

A. TemporaryFolder

    取得在 temporary app data store 中的根目录。该目录下所建立的文件或目录,有可以随时会被系统清除。

可透过 protocol 的方式进行存取:“”。操作方式如下:

private async void HandleTemporaryFolder()
{
    StorageFolder tempFolder = ApplicationData.Current.TemporaryFolder;
 
    // 建立一个文件,设定 CreationCollisionOption 如果既有文件就覆写
    StorageFile sampleFile = await tempFolder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);
 
    String content = "temporary data, write to temporary folder.";
 
    // 利用 FileIO.WriteTextAsync 将内容写入
    await FileIO.WriteTextAsync(sampleFile, content);
}
 
async void TemporaryFolder()
{
    try
    {
        StorageFolder tempFolder = ApplicationData.Current.TemporaryFolder;
        StorageFile sampleFile = await tempFolder.GetFileAsync("sample.txt");
        String content = await FileIO.ReadTextAsync(sampleFile);
    }
    catch (Exception)
    {
        // 文件不存在
    }
}


ApplicationData.LocalCacheFolder

   仅 Windows Phone 支持的目录。该目录保存的文件与目录将不会被备份与还原。

[补充]

a. WP 8.1 与 Store App 的操作有些不同,可参考 的说明,如下:

   InternetClient
   InternetClientServer

‧And, if applicable, the domain credentials capability:
   EnterpriseAuthentication

You must add File Type Associations to your app manifest that declare specific file types that your app can access in this location.
Location Capability Windows.Storage API
Documents
(Windows Store app only)
DocumentsLibrary
You must add File Type Associations to your app manifest that declare specific file types that your app can access in this location.

Use this capability if your app:
‧Facilitates cross-platform offline access to specific OneDrive content using valid OneDrive URLs or Resource IDs

‧Saves open files to the user’s OneDrive automatically while offline
KnownFolders.DocumentsLibrary
Download
(Windows Store app only)
By default, your app can only access files and folders in the user's Downloads folder that your app created. DownloadsFolder
Music MusicLibrary
For more info about accessing media libraries from a Windows Phone app, seeAccess media libraries in Windows Phone apps.
KnownFolders.MusicLibrary
Pictures

PicturesLibrary

For more info about accessing media libraries from a Windows Phone app, seeAccess media libraries in Windows Phone apps.

KnownFolders.PicturesLibrary
Videos VideosLibrary
For more info about accessing media libraries from a Windows Phone app, seeAccess media libraries in Windows Phone apps.
KnownFolders.VideosLibrary
Removable devices RemovableDevices
You must add File Type Associations to your app manifest that declare specific file types that your app can access in this location.

For more info about accessing an SD card from a Windows Phone app, seeAccess the SD card in Windows Phone apps.
KnownFolders.RemovableDevices
Homegroup libraries
(Windows Store app only)
At least one of the following capabilities is needed.
‧MusicLibrary
‧PicturesLibrary
‧VideosLibrary
KnownFolders.HomeGroup
Media Server devices (DLNA)
(Windows Store app only)
At least one of the following capabilities is needed.
‧MusicLibrary
‧PicturesLibrary
‧VideosLibrary
KnownFolders.MediaServerDevices
Universal Naming Convention (UNC) folders
(Windows Store app only)
A combination of the following capabilities is needed.

‧The home and work networks capability:
   PrivateNetworkClientServer

‧And at least one internet and public networks capability:
Retrieve a folder using:
StorageFolder.GetFolderFromPathAsync

Retrieve a file using:
StorageFile.GetFileFromPathAsync

======

以上是介绍操作 ApplicationData 的几个重要的类与规范。希望对入门 WP 8.1 开发的人有所帮助。

其中我觉得如果您有开发 Universal app 的项目,Roaming app 真的是不错的用途,虽然可用的数据量不大,

但随着设备的进化我相信还是够用来同步一些 App 的设定与操作。

References:

〉Working with data and files (XAML)

〉Managing app data (XAML) (重要)

〉File access and permissions in Windows Store apps (重要)

〉Packaging your Store app by using Visual Studio

〉Developing apps (XAML)

〉Windows Phone Store APP Lifecycle and Background Processing

〉Launching, resuming, and multitasking (XAML)

〉Quickstart: Local app data (XAML)

〉How to index app local data (Windows Store app Only)

〉Quickstart: Roaming app data (XAML)

〉Quickstart: Temporary app data (XAML)

〉How to roam data between a Windows Store app and a Windows Phone Store app (重要)

〉Accessing data and files (XAML)

〉Sharing and exchanging data (XAML)

〉Transferring a file from a network resource (XAML)

〉Encrypting data and working with certificates (XAML)

〉Accessing app data with the Windows Runtime

〉Windows.Storage namespace

〉Windows.ApplicationModel namespace

〉Windows Phone 8.1 for Developers – Application Data (重要)

Dotblogs Tags: Windows Phone ,WP8.1


原文:大专栏  Windows Phone 8.1 - 操作 ApplicationData


猜你喜欢

转载自www.cnblogs.com/chinatrump/p/11516573.html