• 【WP8】自定义配置存储类


    之前在WP7升级到WP8的时候遇到配置不兼容的问题

    情景:之前只有一个WP7版本,现在需要发布WP8版本,让用户可以从原来的WP7版本升级到WP8版本

      一般情况下从WP7升级到WP8没什么问题

      但是在项目中升级到WP8的时候,原先在WP7下保存在IsolatedStorageSettings的数据都不出来,经过调试发现

    1、IsolatedStorageSettings存放数据的隔离存储控件的"__ApplicationSettings"文件中,存放的格式如下 {"test":"TestData"}

    <ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <KeyValueOfstringanyType>
            <Key>test</Key>
            <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>
        </KeyValueOfstringanyType>
    </ArrayOfKeyValueOfstringanyType>

    2、但是原来的项目中使用了友盟WP7版本,后来的项目中使用的是WP8版本,友盟会向"__ApplicationSettings"文件中写入数据,如下:

    UmengSDK.Business.OnlineConfigManager+OnlineConfig, UmengAnalyticsWP7, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
    <ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <KeyValueOfstringanyType>
            <Key>test</Key>
            <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>
        </KeyValueOfstringanyType>
        <KeyValueOfstringanyType>
            <Key>device_id</Key>
            <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">0BBB2DF41DD5688A25517F2968339DC0</Value>
        </KeyValueOfstringanyType>
        <KeyValueOfstringanyType>
            <Key>wp_device</Key>
            <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">1C43AC07795C55C2ADA78B0DD5A79B3660A7D137</Value>
        </KeyValueOfstringanyType>
        <KeyValueOfstringanyType>
            <Key>config</Key>
            <Value xmlns:d3p1="http://schemas.datacontract.org/2004/07/UmengSDK.Business" i:type="d3p1:OnlineConfigManager.OnlineConfig">
                <d3p1:Interval>30</d3p1:Interval>
                <d3p1:LastConfigTime>Wed Jul 02 00:43:35 CST 2014</d3p1:LastConfigTime>
                <d3p1:Policy>BATCH_AT_LAUNCH</d3p1:Policy>
            </Value>
        </KeyValueOfstringanyType>
    </ArrayOfKeyValueOfstringanyType>

    3、而上面数据到了WP8上就不能正常读取原来存放的数据(如果在WP8项目中用WP7版的友盟则可以正常读取),导致原来存放的其他信息也读取不出来

    4、下面试图自定义一个与 IsolatedStorageSettings 功能类似的类用于小数据的存取,避免第三方类库对"__ApplicationSettings"文件的修改导致一些兼容性问题

      IsolatedStorageSettings 存放的是键值对,也就是字典模型,我们需要把Dictionary序列化到文件中,但是Dictionary不支持直接序列化,先对Dictionary进行扩展,让其支持序列化

    using System;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    
    namespace XTuOne.Common.Helpers
    {
        /// <summary>
        /// 可序列化的Dictionary
        /// </summary>
        [XmlRoot("Dictionary")]
        public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
        {
            #region 构造函数,调用基类的构造函数
    
            public SerializableDictionary()
            {
            }
    
            public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
                : base(dictionary)
            {
            }
    
    
            public SerializableDictionary(IEqualityComparer<TKey> comparer)
                : base(comparer)
            {
            }
    
    
            public SerializableDictionary(int capacity)
                : base(capacity)
            {
            }
    
            public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
                : base(capacity, comparer)
            {
            }
    
            public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
                : base(dictionary, comparer)
            {
            }
    
            #endregion
    
            #region IXmlSerializable 接口的实现
    
            public XmlSchema GetSchema()
            {
                throw new NotImplementedException();
            }
    
            /// <summary>
            /// 从对象的XML表示形式生成该对象
            /// </summary>
            /// <param name="reader"></param>
            public void ReadXml(XmlReader reader)
            {
                var keySerializer = new XmlSerializer(typeof (TKey));
                var valueSerializer = new XmlSerializer(typeof (TValue));
                bool wasEmpty = reader.IsEmptyElement;
                reader.Read();
    
                if (wasEmpty)
                    return;
                while (reader.NodeType != XmlNodeType.EndElement)
                {
                    reader.ReadStartElement("Key");
                    TKey key = (TKey) keySerializer.Deserialize(reader);
                    reader.ReadEndElement();
    
                    reader.ReadStartElement("Value");
                    TValue value = (TValue) valueSerializer.Deserialize(reader);
                    reader.ReadEndElement();
                    this.Add(key, value);
                    reader.MoveToContent();
                }
                reader.ReadEndElement();
            }
    
    
            /// <summary>
            /// 将对象转换为其XML表示形式
            /// </summary>
            /// <param name="writer"></param>
            public void WriteXml(XmlWriter writer)
            {
                var keySerializer = new XmlSerializer(typeof (TKey));
                var valueSerializer = new XmlSerializer(typeof (TValue));
                foreach (TKey key in this.Keys)
                {
                    writer.WriteStartElement("Key");
                    keySerializer.Serialize(writer, key);
                    writer.WriteEndElement();
    
                    writer.WriteStartElement("Value");
                    TValue value = this[key];
                    valueSerializer.Serialize(writer, value);
                    writer.WriteEndElement();
                }
            }
    
            #endregion
        }
    }
    View Code

    5、使用系统的Xml序列化功能保存数据

    using System;
    using System.IO;
    using System.IO.IsolatedStorage;
    using System.Windows;
    using System.Xml.Linq;
    using System.Xml.Serialization;
    
    namespace XTuOne.Common.Helpers
    {
        public class XmlHelper
        {
            private XmlHelper()
            {
            }
    
            /// <summary>
            /// 序列化对象到文件
            /// </summary>
            /// <param name="file">文件路径:"/test.xml"</param>
            /// <param name="obj"></param>
            public static void Serialize<T>(string file, T obj)
            {
                using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (var fs = new IsolatedStorageFileStream(file, FileMode.OpenOrCreate, FileAccess.Write, sf))
                    {
                        var serializer = new XmlSerializer(obj.GetType());
                        serializer.Serialize(fs, obj);
                    }
                }
            }
    
            /// <summary>
            /// 反序列化文件到对象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="file">文件路径:"/test.xml"</param>
            public static T Deserialize<T>(string file)
            {
                using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    var serializer = new XmlSerializer(typeof(T));
                    using (var fs = sf.OpenFile(file, FileMode.Open, FileAccess.Read))
                    {
                        return (T)serializer.Deserialize(fs);
                    }
                }
            }
    
            /// <summary>
            /// 读取配置文件的信息
            /// </summary>
            /// <param name="file">前面不加/</param>
            /// <param name="node">用.隔开(例如App.Version)</param>
            /// <param name="attribute"></param>
            public static string GetConfigValue(string file,string node, string attribute)
            {
                var configFile = Application.GetResourceStream(new Uri(file, UriKind.Relative));
                return GetXmlValue(configFile.Stream, node, attribute);
            }
    
            private static string GetXmlValue(Stream stream, string node, string attribute)
            {
                var configDoc = XDocument.Load(stream);
                XElement temp = null;
                foreach (var n in node.Split('.'))
                {
                    if (temp == null)
                    {
                        temp = configDoc.Element(n);
                        continue;
                    }
                    temp = temp.Element(n);
                }
    
                if (temp == null)
                {
                    throw new NullReferenceException();
                }
                return temp.Attribute(attribute).Value;
            }
    
        }
    }
    XmlHelper
    // *************************************************
    // 
    // 作者:bomo
    // 小组:WP开发组
    // 创建日期:2014/6/21 14:55:56
    // 版本号:V1.00
    // 说明:
    // 
    // *************************************************
    // 
    // 修改历史: 
    // Date                WhoChanges        Made 
    // 2014/6/21 14:55:56            bomo         Initial creation 
    //
    // *************************************************
    
    using System.IO;
    using System.IO.IsolatedStorage;
    using XTuOne.Common.Helpers;
    
    namespace XTuOne.Utility.Helpers
    {
        /// <summary>
        /// 自定义应用程序配置(相当于IsolatedStorageSetting)
        /// </summary>
        public class ApplicationSetting
        {
            /// <summary>
            /// 保存配置的文件名
            /// </summary>
            private readonly string filePath;
    
            private readonly SerializableDictionary<string, object> dictionary;
    
            public ApplicationSetting(string filePath)
            {
                this.filePath = filePath;
                //读取配置
                using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    var directory = Path.GetDirectoryName(filePath);
                    if (directory != null)
                    {
                        if (sf.DirectoryExists(directory))
                        {
                            sf.CreateDirectory(directory);
                        }
                    }
    
                    dictionary = sf.FileExists(filePath)
                        ? XmlHelper.Deserialize<SerializableDictionary<string, object>>(filePath)
                        : new SerializableDictionary<string, object>();
                }
            }
    
            /// <summary>
            /// 通过索引赋值需要显式保存
            /// </summary>
            public object this[string key]
            {
                get { return Contains(key) ? dictionary[key] : null; }
                set { dictionary[key] = value.ToString(); }
            }
    
            public T Get<T>(string key)
            {
                return (T) dictionary[key];
            }
    
            /// <summary>
            /// 通过键获取值,如果不存在,则返回传入的默认值
            /// </summary>
            public T Get<T>(string key, T defaultValue)
            {
                return dictionary.ContainsKey(key) ? (T) dictionary[key] : defaultValue;
            }
    
            /// <summary>
            /// 设置值,自动保存
            /// </summary>
            public void Set(string key, object value)
            {
                if (dictionary.ContainsKey(key))
                {
                    dictionary[key] = value;
                }
                else
                {
                    dictionary.Add(key, value);
                }
                Save();
            }
    
            /// <summary>
            /// 保存配置到文件
            /// </summary>
            public void Save()
            {
                XmlHelper.Serialize(filePath, dictionary);
            }
    
            /// <summary>
            /// 判断是否包含键
            /// </summary>
            public bool Contains(string key)
            {
                return dictionary.ContainsKey(key);
            }
    
            /// <summary>
            /// 析构时保存数据
            /// </summary>
            ~ApplicationSetting()
            {
                Save();
            }
        }
    }

    使用自定义的配置管理器可以控制文件信息,不会出现上述与第三方类库的一些兼容性问题(当然,这种情况比较少)

    注意:该配置文件只支持基础类型,不支持复杂类型

  • 相关阅读:
    面经-新浪
    面经-中兴
    面经-趋势科技
    面经-酷家乐
    面经-大华
    面经-明略科技
    面经-小米
    面经-虹软
    coroutine
    Coroutine 终止协程和异常处理
  • 原文地址:https://www.cnblogs.com/bomo/p/3819390.html
Copyright © 2020-2023  润新知