下载图像并将其保存到 Application.persistentDataPath 中挂起应用程序
Download and save image into Application.persistentDataPath hangs the app
我写了一个游戏,可以从服务器下载图片,然后将它们存储在 Application.persistentDataPath。
我的问题是在保存少量图像时场景挂起,保存完成后,它会执行其余代码。
我该如何解决这个问题?
正在将图像保存到设备本地存储中:
if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
Debug.Log (imagesPathPrefix + " already exists.");
return;
}
File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);
您可以创建一个 Thread
来执行您的操作。这是一个例子:
class FileDownloader
{
struct parameterObject
{
public string url;
public string savePath;
}
static void downloadfunction(object data)
{
parameterObject obj = (parameterObject)data;
if (File.Exists(obj.savePath))
return;
using (WebClient Client = new WebClient())
{
Client.DownloadFile(obj.url, obj.savePath);
}
}
public static void downloadfromURL(string url, string savePath)
{
parameterObject obj = new parameterObject();
obj.url = url;
obj.savePath = savePath;
Thread thread = new Thread(FileDownloader.downloadfunction);
thread.Start(obj);
}
}
注意:如果您要在下载后立即使用图像,请不要使用线程。 Unity3d 不是线程安全的。
您必须在后台执行此操作,以免锁定主线程。
但请记住,Unity API 不支持多线程,因此只能在此处完成其他 processes/calculations。所有 Unity API 调用都必须在后台任务完成后在主线程中进行。有很多方法可以做到这一点,比如后台工作者、线程、线程池等。
用线程做:
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
Debug.Log (imagesPathPrefix + " already exists.");
return;
}
File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);
}).Start();
或者使用线程池:
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
Debug.Log (imagesPathPrefix + " already exists.");
return;
}
File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);
}, null);
我还没有测试过这些,但它们应该可以工作。
--- 已更新 (6 月 18 日)----
使用 AssetBundles 从服务器管理我的动态内容。
抱歉,但下面提供的 none 解决方案实际上有效,因为我已经尝试了所有这些解决方案,其中一些与我可以通过 Internet 找到的相似。
在一些研究中,这是我发现的:
"Basically, anything that UnityEngine makes available to you can't be touched in a thread you create with System.Threading."
"The only thing you can't do is use Unity API methods themselves across different threads, as they are not thread-safe, but that won't prevent you from doing background processing tasks."
我实际上"solved"这个问题。
应用程序只有在计算机上 运行s 时才会挂起,从服务器下载图像并将它们保存到 Application.persistentDataPath。
但是,它在构建时不会挂起,运行 在我的移动设备上,使用相同的代码。
在没有互联网连接中断的情况下,我检查了那些大图像是否已完全下载并很好地存储在 persistentDataPath 中。
尽管这对我来说不再是问题,但仍然感到尴尬和不愉快。
我希望遇到这个问题的人至少可以尝试我的方法,检查应用程序构建时是否 "hanged" 并且在您的设备上 运行 ,特别是将大图像文件保存到设备本地存储,而不是 运行ning 在您的计算机中。
我写了一个游戏,可以从服务器下载图片,然后将它们存储在 Application.persistentDataPath。
我的问题是在保存少量图像时场景挂起,保存完成后,它会执行其余代码。
我该如何解决这个问题?
正在将图像保存到设备本地存储中:
if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
Debug.Log (imagesPathPrefix + " already exists.");
return;
}
File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);
您可以创建一个 Thread
来执行您的操作。这是一个例子:
class FileDownloader
{
struct parameterObject
{
public string url;
public string savePath;
}
static void downloadfunction(object data)
{
parameterObject obj = (parameterObject)data;
if (File.Exists(obj.savePath))
return;
using (WebClient Client = new WebClient())
{
Client.DownloadFile(obj.url, obj.savePath);
}
}
public static void downloadfromURL(string url, string savePath)
{
parameterObject obj = new parameterObject();
obj.url = url;
obj.savePath = savePath;
Thread thread = new Thread(FileDownloader.downloadfunction);
thread.Start(obj);
}
}
注意:如果您要在下载后立即使用图像,请不要使用线程。 Unity3d 不是线程安全的。
您必须在后台执行此操作,以免锁定主线程。 但请记住,Unity API 不支持多线程,因此只能在此处完成其他 processes/calculations。所有 Unity API 调用都必须在后台任务完成后在主线程中进行。有很多方法可以做到这一点,比如后台工作者、线程、线程池等。
用线程做:
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
Debug.Log (imagesPathPrefix + " already exists.");
return;
}
File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);
}).Start();
或者使用线程池:
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
Debug.Log (imagesPathPrefix + " already exists.");
return;
}
File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);
}, null);
我还没有测试过这些,但它们应该可以工作。
--- 已更新 (6 月 18 日)----
使用 AssetBundles 从服务器管理我的动态内容。
抱歉,但下面提供的 none 解决方案实际上有效,因为我已经尝试了所有这些解决方案,其中一些与我可以通过 Internet 找到的相似。
在一些研究中,这是我发现的:
"Basically, anything that UnityEngine makes available to you can't be touched in a thread you create with System.Threading."
"The only thing you can't do is use Unity API methods themselves across different threads, as they are not thread-safe, but that won't prevent you from doing background processing tasks."
我实际上"solved"这个问题。
应用程序只有在计算机上 运行s 时才会挂起,从服务器下载图像并将它们保存到 Application.persistentDataPath。
但是,它在构建时不会挂起,运行 在我的移动设备上,使用相同的代码。
在没有互联网连接中断的情况下,我检查了那些大图像是否已完全下载并很好地存储在 persistentDataPath 中。
尽管这对我来说不再是问题,但仍然感到尴尬和不愉快。
我希望遇到这个问题的人至少可以尝试我的方法,检查应用程序构建时是否 "hanged" 并且在您的设备上 运行 ,特别是将大图像文件保存到设备本地存储,而不是 运行ning 在您的计算机中。