将图像下载并保存到Application.persistentDataPath中会挂起应用程序

时间:2015-05-12 11:12:07

标签: c# image unity3d download save

我写了一个游戏,可以从服务器下载图像,然后将它们存储在Application.persistentDataPath中。

我的问题是当保存场景挂起的少量图像时,保存时会执行剩下的代码。

我该如何解决这个问题?

将图像保存到设备本地存储中:

    if (File.Exists (Application.persistentDataPath + "/LayoutImages/")) {
        Debug.Log (imagesPathPrefix + " already exists.");
        return;
    }

    File.WriteAllBytes (Application.persistentDataPath + "/LayoutImages/abc.jpg", image);

3 个答案:

答案 0 :(得分:2)

您可以创建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不是线程安全的。

答案 1 :(得分:1)

您必须在后台执行此操作,因此它不会锁定主线程。 但请记住,Unity API不支持多线程,因此只能在此处完成其他进程/计算。在后台任务完成后,必须在主线程中进行所有Unity API调用。有很多方法可以像backgroundworkers,threads,threadPools等那样做。

用线程做:

        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);

我还没有测试过这些,但它们应该有用。

答案 2 :(得分:1)

--- 已更新 (6月18日) ----

使用 AssetBundles 管理来自服务器的动态内容。

很抱歉,以下提供的解决方案都没有实际工作,因为我已经尝试了所有这些解决方案,其中一些与我通过互联网找到的类似。

在一些研究中,这是我发现的:

"基本上,UnityEngine提供的任何内容都无法在您使用System.Threading创建的主题中触及。"

"你唯一能做的就是在不同的线程中使用Unity API方法,因为它们不是线程安全的,但是这不会妨碍你做背景处理任务。"

我实际上已经解决了#34;这个问题。

该应用仅在计算机上运行时挂起,从服务器下载图像并将其保存到Application.persistentDataPath。

但是,在相同的代码下,在我的移动设备上构建和运行它时,它不会挂起。

在没有互联网连接中断的情况下,我已经检查过这些大型图片是否已完全下载并存储在persistentDataPath中。

感觉尴尬和不愉快,即使它不再是我的问题。

我希望那些遇到这个问题的人至少可以尝试我的方法,检查它是否是"被绞死"当应用程序在您的设备上构建并运行时,尤其是将大图像文件保存到设备本地存储中,而不是在您的计算机上运行。