我正在用一些XML文件中的数据填充一些元素,例如ScrollView。通过单击按钮,将从服务器中获取最新文件。 我试图直接在GUI中显示它们,但是我总是必须重新启动应用程序才能查看最新下载的版本。 下载和编写工作正常。
以下是一些代码:
首先是下载/更新过程
public bool update() {
try {
// Download + Save
WebClient wc = new WebClient();
wc.Credentials = new NetworkCredential("anonymous", "");
wc.DownloadFile(_address_employeesXML, _filePathToXMLImport + "/employees.xml");
XMLReader test = new XMLReader(logController);
test.readXMLFiles();
Debug.Log("Update successful");
} catch (Exception e) {
#if UNITY_EDITOR
EditorUtility.DisplayDialog("Error", e.Message, "OK");
#endif
XMLReader test = new XMLReader(logController);
//test.readXMLFiles();
Debug.LogException(e);
return false;
}
return true;
}
然后读取过程:
public bool readEmployees()
{
string pathToEmployeeXML = _filePathToXMLImport + "/employees.xml";
if (File.Exists(pathToEmployeeXML))
{
using (XmlReader reader = XmlReader.Create(pathToEmployeeXML))
{
while (reader.Read())
{
// Only detect start elements.
if (reader.IsStartElement())
{
switch(reader.Name)
{
case "employee":
XmlReader inner = reader.ReadSubtree();
inner.ReadToDescendant("firstName");
string firstName = inner.ReadElementString();
inner.ReadToDescendant("lastName");
string lastName = inner.ReadElementString();
generateEmployee(firstName, lastName);
break;
}
}
}
}
return true;
}
return false;
}
我发现了这个线程: Reloading XML asset in Unity 不幸的是,这并不能真正解决我的问题。
我还尝试使用AssetDatabase.Refresh,但实际上并没有真正找到实现它的方法。
答案 0 :(得分:0)
我希望使整个过程异步,以免使用UnityWebRequest
进行下载来阻止主线程。
实际上,您实际上不必真正写入文件并再次读取它……您可以直接使用下载的string
并将其传递给XmlSerializer
(您必须实现一个表示xml布局的类-请参见Saving and Loading Data: XmlSerializer)。
如果您仍然需要/想写,我会写到Application.persitentDataPath
并使用FileStream
读/写文件
public void update(Action<bool> success)
{
StartCoroutine(UpdateRoutine(onSuccess));
}
private string authenticate(string username, string password)
{
string auth = username + ":" + password;
auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
auth = "Basic " + auth;
return auth;
}
private IEnumerator UpdateRoutine (Action<bool> onSuccess)
{
using(var www = UnityWebRequest.Get(_address_employeesXML)
{
string authorization = authenticate("YourUserName", "YourPassWord");
www.SetRequestHeader("AUTHORIZATION", authorization);
yield return www.SendRequest();
if(www.error)
{
success?.Invoke(false);
}
else
{
// you could ofcourse simply use the returned filecontent now like
var xml = www.downloadHandler.text;
var xmlSerializer = new XmlSerializer(typeof(YOURDATA_CLASS));
var dataClass = (YOURDATA_CLASS) xmlSerializer.Deserialize(xml);
success?.Invoke(true);
// However if you prefer to write the file
WriteFile(xml, success);
}
}
}
// Usually async void is bad
// but with a callback its fine
private async void WriteFile(string xml, Action<bool> success)
{
try
{
var data = Encoding.UTF8.GetBytes(xml);
using(var file = File.Open(Path.Combine(_filePathToXMLImport, "employees.xml", FileMode.OpenOrCreate))
{
await file.WriteAsync(data, 0, data.length);
success?.Invoke();
}
}
catch
{
success?.Invoke(false);
}
}
然后读取过程:
public void ReadFile(Action<bool> success)
{
using(var file = File.Open(Path.Combine(_filePathToXMLImport, "employees.xml", FileMode.Open))
{
var data = new byte[(int)file.length];
await file.ReadAsync(data, 0, data.length);
var xml = Encoding.UTF8.GetString(Data);
var xmlSerializer = new XMLSerializer(typeof(YOURDATA_CLASS));
var dataClass = (YOURDATA_CLASS) xmlSerializer.Deserialize(xml);
success?.Invoke(true);
}
}
注意:在智能手机上键入内容,因此没有保修,但我希望这个主意会清楚
答案 1 :(得分:0)
解决我的问题的方法是将我上面提到的代码移到负责StartView的Controller类中。