前些天将在windows上做好的程序发布一个Android版本,要拿出去给人家看看,本来最初我是做了针对各个平台的xml反序列化的,按照网上大多数说的路径如下:
根目录:StreamingAssets文件夹
#if UNITY_EDITOR
string filepath = Application.dataPath +"/StreamingAssets"+"/my.xml";
#elif UNITY_IPHONE
string filepath = Application.dataPath +"/Raw"+"/my.xml";
#elif UNITY_ANDROID
string filepath = "jar:file://" + Application.dataPath + "!/assets/"+"/my.xml; //只是文件看似在那里,并不能直接使用
#endif
发布一个apk出来,将其解压,发现跟网上说的路径是一致的,但是Android真机上就是读取不了,后来用File exists查看,返回false,就是说找不到这个文件,当时很纳闷,路径看上去应该没错的,怎么就不行呢,后来查到Android好像不能通过这个路径读取,在真机中文件都是以包的形式存在的,所以只能通过resource load 或者www的方式获取了然后再读出来。我选择了WWW的方式读取相关资源文件。
我的项目的相关xml在assets/StreamingAssets/AssetBundles/下,(记住:要想读取到必须放到StreamingAssets下)
针对各个平台的xml反序列化相关代码如下:
using System; using System.IO; using System.Xml.Serialization; using UnityEngine; using System.Text; using Game.Jeson.Utils; namespace Game.Jeson.Utils { public class SerializeXmlUtils { FileInfo fileInfo; string _data; string _filename; /// <summary> /// 读取/StreamingAssets/AssetBundles/文件夹下指定的文件 /// </summary> /// <param name="filename">文件名,如果文件所在目录是AssetBundles的子目录,则必须带上</param> /// <returns></returns> public static Stream LoadXML(string filename) { MemoryStream memoryStream = null; string data = string.Empty; string fullFileName = filename; FileInfo fileInfo = null; if (Application.platform == RuntimePlatform.IPhonePlayer) { fullFileName = Application.dataPath + "/Raw/AssetBundles/" + filename; fileInfo = new FileInfo(fullFileName); StreamReader r = fileInfo.OpenText(); data = r.ReadToEnd(); r.Close(); } else if (Application.platform == RuntimePlatform.Android) { fullFileName = Application.streamingAssetsPath + "/AssetBundles/" + filename; // WWW类会即时返回,导致后面于此相关的操作就会失败 // 我们读文件的时候还是需要阻塞,不然真心坑爹 //StartCoroutine(LoadWWW()); WWW www = new WWW(fullFileName); while (www.error == null && !www.isDone) ; data = www.text; } else { fullFileName = Application.dataPath + "/StreamingAssets/AssetBundles/" + filename; fileInfo = new FileInfo(fullFileName); StreamReader r = fileInfo.OpenText(); data = r.ReadToEnd(); r.Close(); } if (data.ToString() != string.Empty) { byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(data); memoryStream = new MemoryStream(byteArray,true); } return memoryStream; } /// <summary> /// 将指定的xml文件反序列化为对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="path"></param> /// <returns></returns> public static T DeserializeXml<T>(string path) where T : class { MemoryStream memoryStream = SerializeXmlUtils.LoadXML(path) as MemoryStream; //Debug.LogError("memoryStream == null ? " + (memoryStream == null)); if (memoryStream == null) return null; T t; try { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); T t1 = xmlSerializer.Deserialize(memoryStream) as T; if (t1 == null) { return (T)null; } else { t = t1; } } catch (Exception) { return (T)null; } finally { memoryStream.Close(); } return t; } } }