使用 Kotlin 和 Android NDK C++ 的 Android 资产 FileNotFound 异常

发布于 2025-01-17 20:32:16 字数 2377 浏览 1 评论 0 原文

我正在尝试通过将 AssetManager 对象从我的kotlin脚本传递到jni接口,在资产/文件夹中读取 .obj 文件。可以使用C ++来解析 .obj 文件,然后将其添加到我的OpenGL场景中。但是该应用程序没有在我的资产文件夹中找到任何文件。

我抓住了AssetManager,并尝试将其传递给渲染器类内部的JNI,在 onSurfaceCecreated callback:

kotlin文件:

private external fun loadModels(assetManager: AssetManager): Void //Loaded correctly from companion object
private lateinit var manager: AssetManager
override fun onSurfaceCreated(unused: GL10, config: EGLConfig?) {
    manager = Resources.getSystem().assets //Gets the asset manager (poorly documented)
    loadModels(manager)
    manager.open("hello.txt") //Throws FileNotFoundException
}

C ++文件:C ++文件:

#include <jni.h>
#include <android/log.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

extern "C" JNIEXPORT jobject JNICALL
Java_com_example_mypackage_glRenderer_loadModels(JNIEnv *env, jobject thiz, jobject asset_manager) {
    AAssetManager* pAssetManager = AAssetManager_fromJava(env, asset_manager);
    if (pAssetManager == nullptr) {
        __android_log_print(ANDROID_LOG_ERROR, "GL_JNIConnector.cpp", "Failed to load asset manager");
        //Break
        exit(1);
    }
    //Loop through all files in Models folder
    AAssetDir* pModelsDirectory = AAssetManager_openDir(pAssetManager, "Models/");
    //AAssetDir_rewind(pModelsDirectory);
    const char* filename = AAssetDir_getNextFileName(pModelsDirectory); //Incorrectly returns NULL
    __android_log_print(ANDROID_LOG_DEBUG, "GL_JNIConnector.cpp", "%s", filename);
}

但是我的 aassetdir_getnexnextfilectfilename(pmodelsdirectory)(pmodelsdirectory)保持返回 null ,当我的资产文件夹中存在文件时,解压缩.APK文件也显示它们已正确添加到应用程序中。

我通过编造 Hello.txt 文件,然后尝试使用 Manager.open(“ H​​ello..txt”)在Kotlin中对其进行了测试。 a filenotfoundException

这是我的目录:

用Android Studio拆开APK,在 .apk 文件

I am trying to read .obj files in the assets/ folder by passing the AssetManager object from my Kotlin script to the JNI interface, where I can use C++ to parse the .obj files and add it to my OpenGL scene. But the app is not finding any files in my assets folder.

I grab the AssetManager and attempt to pass it to my JNI inside of my renderer class, under the OnSurfaceCreated callback:

Kotlin File:

private external fun loadModels(assetManager: AssetManager): Void //Loaded correctly from companion object
private lateinit var manager: AssetManager
override fun onSurfaceCreated(unused: GL10, config: EGLConfig?) {
    manager = Resources.getSystem().assets //Gets the asset manager (poorly documented)
    loadModels(manager)
    manager.open("hello.txt") //Throws FileNotFoundException
}

C++ file:

#include <jni.h>
#include <android/log.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

extern "C" JNIEXPORT jobject JNICALL
Java_com_example_mypackage_glRenderer_loadModels(JNIEnv *env, jobject thiz, jobject asset_manager) {
    AAssetManager* pAssetManager = AAssetManager_fromJava(env, asset_manager);
    if (pAssetManager == nullptr) {
        __android_log_print(ANDROID_LOG_ERROR, "GL_JNIConnector.cpp", "Failed to load asset manager");
        //Break
        exit(1);
    }
    //Loop through all files in Models folder
    AAssetDir* pModelsDirectory = AAssetManager_openDir(pAssetManager, "Models/");
    //AAssetDir_rewind(pModelsDirectory);
    const char* filename = AAssetDir_getNextFileName(pModelsDirectory); //Incorrectly returns NULL
    __android_log_print(ANDROID_LOG_DEBUG, "GL_JNIConnector.cpp", "%s", filename);
}

But my AAssetDir_getNextFileName(pModelsDirectory) keeps returning NULL, when the files are present in my assets folder, AND unzipping the .apk file also shows they were added to the app correctly.

I tested it within the Kotlin by making up a hello.txt file and trying to access it in Kotlin using manager.open("hello.txt") and this also throws a FileNotFoundException

This is my directory:

Image of assets directory

Even hovering over the filename in my code points to the file in my assets folder, why can't the app find it in runtime?

Pulling apart the APK with Android Studio shows my assets folder intact in the .apk file

Image of Android Studio APK Analyzer

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放低过去 2025-01-24 20:32:16

问题是我使用了我的资产管理器

manager = Resources.getSystem().assets

,它只能让我访问系统资源,而不能访问应用程序资源。相反,我应该将上下文从表面视图类传递到渲染器类,

//Surface View Class
class glSurfaceView(context: Context, attrs: AttributeSet) : GLSurfaceView(context, attrs)
//Renderer Class
class glRenderer(private val context: Context) : GLSurfaceView.Renderer

以便我可以简单地使用我的资产管理器

manager = context.assets

感谢@Michael 指出这一点

The issue was I grabbed my asset manager using

manager = Resources.getSystem().assets

which only gets me access to system resources, not application resources. Instead, I should have passed my context from my surface view class to the renderer class

//Surface View Class
class glSurfaceView(context: Context, attrs: AttributeSet) : GLSurfaceView(context, attrs)
//Renderer Class
class glRenderer(private val context: Context) : GLSurfaceView.Renderer

so that I could get my asset manager simply using

manager = context.assets

Thanks to @Michael for pointing that out

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文