Load and save the image in Application.persistentDataPath.

I wrote a game that can download images from the server and then store them inside Application.persistentDataPath.

My problem is that when saving multiple images the plot is hanging and when done with saving it executes the rest of the code.

How can I solve this problem?

Saving an image to the local storage of the device:

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

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

      

+3


source to share


3 answers


--- Updated (Jun 18) ----

Use AssetBundles to manage my dynamic content from the server.


Sorry, but none of the solutions below work as I've tried all of them and some of them are similar to what I could find over the internet.

During some research, this is what I found:

"Basically, whatever UnityEngine provides you cannot be touched by a thread created with System.Threading."

"The only thing you cannot do is use the Unity API methods themselves on different threads, as they are not thread safe, but that will not prevent you from performing background tasks."




I actually "solved" this problem.

The application will hang only when it is launched on the computer, loading images from the server and storing them in Application.persistentDataPath.

However, it won't hang when it is created and launched on my mobile devices under the same codes.

Without interrupting the internet connection, I have verified that these large images are fully loaded and saved in the persistentDataPath file.

Feel uncomfortable and unpleasant, although this is no longer a problem for me.

I wish those who are facing this problem can at least try my method, check "hangs" when the app is built and run on your device, especially storing large image files in the local storage of the device, working instead into your computer.

+1


source


You can create Thread

to perform the operation from the side. Here's an example:

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

    }
}

      



Note. If you will be using your image immediately after upload, do not use streams. Unity3d is not thread safe.

+2


source


You need to do this in the background so that it doesn't block the main thread. But keep in mind that the Unity API does not support multithreading, so only other processes / calculations can be done here. All Unity API calls had to be made on the main thread after the background task finished. There are ways to do this as background workers, threads, threadPools, etc.

Doing it with threads:

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

      

Or with a threadpool:

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

      

I haven't tested them, but they should work.

+1


source







All Articles