AndroidStudioC#CppNDK开发

UnityNDK开发小试牛刀之NDK实现同步读取Android下的StreamingAssets资源

Spread the love

上一篇文章中我们知道了如何简单编写NDK代码,这时我们就小试牛刀,看看NDK在什么情况下可以为我们所用!

在Unity开发当中StreamingAssets始终是一个比较重要的目录,里面一般会放一些重要的资源,配置等等,在PC以及iOS等平台,我们能够直接通过文件的形式访问到StreamingAssets文件夹下的文件,但是在安卓平台下,这些文件是经过压缩的。
实际上这些资源在android下是通过AssetManager进行管理的。我们可以通过Android的JavaAPI进行直接的读取。如下代码:

但是在实际的使用过程当中我们会发现,如果我们将Java堆当中的bytes直接通过Unity提供的CallFunc的方式调用的话每一次调用都会带来相应bytes大小的GCAlloc,导致大量的GC出现,所以这个时候NDK就需要出来帮忙了。

实际上NDK中的C++代码不仅仅是java虚拟机可以通过jni的方式调用,C#也可以直接通过PInvoke的方式进行调用。

使用ndk读取assetmanager的代码如下:

 

上述的方法第一个直接通过AssetManager读取文件,另外一个则以offset的形式进行读取AssetManager的文件,第三个方法则是直接读取文件,例如沙盒目录的文件就可以使用该方法读取,最后一个则是释放bytes。

接下来我们需要将bytes读取到C#当中:
我们先将方法导出到C#当中:

这样我们就可以直接调用C++的方法了。
然后我们编写读取数据的代码:

可以看到我们这里使用了流作为缓冲区,流里面的buffer可以反复为我们利用,这样我们就可以通过Marshal.Copy不断将数据写入到流中,当我们需要使用的时候我们就可以直接读取数据。
下面同样的,是直接读取文件的方法:

以上,通过这样的方法,我们可以毫无GC地同步读取Android下StreamingAssets的代码。如果不使用Java也不使用NDK的情况下,如果我们使用WWW去加载,不仅仅无法同步读取,其带来的GC也是不可小觑的。

接下去我们可能会提升一些难度,加入UnityNativePlugin以及OpenGLES的内容,有关于NDK调用libpng的内容。

工程地址:
https://github.com/vgvgvvv/ResetCore/tree/master/Unity/NativeReadBytes

发表评论

电子邮件地址不会被公开。 必填项已用*标注