Android Unity-在后台线程上加载文件 [英] Android Unity - Load a file on background thread

查看:150
本文介绍了Android Unity-在后台线程上加载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在应用程序中加载文件,并且由于文件很大(大约250MB),因此需要从主线程执行此加载.而且,由于Android上的资产不是存储在常规目录中,而是存储在jar文件中,因此我需要使用WWW或UnityWebRequest类.

I need to load a file in my application and since it is big ( around 250MB) I need to perform this loading off the main thread. What is more, because assets on Android are not stored in a regular directory, but a jar file, I need to use WWW or UnityWebRequest class.

我最终得到了这样的帮助方法:

I ended up with helper method like that:

public static byte[] ReadAllBytes(string filePath)
{

    if (Application.platform == RuntimePlatform.Android)
    {
        var reader = new WWW(filePath);
        while (!reader.isDone) { }

        return reader.bytes;
    }
    else
    {
        return File.ReadAllBytes(filePath);
    }
}

问题是我不能在后台线程上使用它-Unity不允许我在那里创建WWW对象.如何创建这样的方法,该方法将读取当前线程上的那些字节?

The problem is I cannot use it on background thread - Unity won't allow me to create WWW object there. How can I create a method like this, which will read those bytes on current thread?

推荐答案

我最终得到了以下解决方案.我没有找到加载原始文件主线程的方法,但是我设法将其加载到Coroutine中,并在后台线程上对该文件执行了进一步(也很繁重)的操作.我做了这样的静态方法:

I ended up with the following solution. I did not find a way to load raw file main thread, but I managed to load it in Coroutine and perform further (also heavy) operations on this file on a background Thread. I made a static method like this:

public static void ReadAllBytesInCoroutine(MonoBehaviour context, string filePath, Action<ReadBytesInCoroutineResult> onComplete)
{
    context.StartCoroutine(ReadFileBytesAndTakeAction(filePath, onComplete));
}

private static IEnumerator ReadFileBytesAndTakeAction(string filePath, Action<ReadBytesInCoroutineResult> followingAction)
{
    WWW reader = null;

    try
    {
        reader = new WWW(filePath);
    }
    catch(Exception exception)
    {
        followingAction.Invoke(ReadBytesInCoroutineResult.Failure(exception));
    }

    while (reader != null && !reader.isDone)
    {
        yield return null;
    }
    followingAction.Invoke(ReadBytesInCoroutineResult.Success(reader.bytes));
}

ReadBytesInCoroutineResult是我的简单自定义数据类:

ReadBytesInCoroutineResult is my simple, custom data class:

public class ReadBytesInCoroutineResult
{
    public readonly bool successful;
    public readonly byte[] data;
    public readonly Exception reason;

    private ReadBytesInCoroutineResult(bool successful, byte[] data, Exception reason)
    {
        this.successful = successful;
        this.data = data;
        this.reason = reason;
    }

    public static ReadBytesInCoroutineResult Success(byte[] data)
    {
        return new ReadBytesInCoroutineResult(true, data, null);
    }

    public static ReadBytesInCoroutineResult Failure(Exception reason)
    {
        return new ReadBytesInCoroutineResult(true, null, reason);
    }

}

这样,我有一种机制可以命令在协程中的任何地方加载文件(只要它在主线程上).同步加载文件,但由于协程,它不会阻塞主线程.稍后,我调用此函数,并在单独的线程上获取获取的字节,然后在该线程上执行大量计算.

This way I have a mechanism to order to load a file in coroutine in any place (as long as it is on the main thread). A file is loaded synchronously, but it is not blocking main thread, because of the coroutine. Later I invoke this function and take acquired bytes on a separate thread, where I perform heavy computing on them.

    ResourcesUtils.ReadAllBytesInCoroutine(monoBehavior, filePath, (bytes) => {

        //here I run an async method which takes bytes as parameter

    });

这篇关于Android Unity-在后台线程上加载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆