Android NDK: почему AAssetManager_open возвращает NULL

У меня есть код:

AAsset* pAsset = AAssetManager_open(pAssetManager, "asset_test.txt", AASSET_MODE_STREAMING);
DebugPrint(pAsset?"pAsset not NULL\n":"pAsset NULL");
if (pAsset)
{
    char buf[1024];
    AAsset_read(pAsset, buf, sizeof(buf));
    DebugPrint(buf);
    AAsset_close(pAsset);
}

Этот код всегда печатает "pAsset NULL" в logcat.

Я поместил файл asset_test.txt в свой каталог ресурсов и посмотрел в.apk, чтобы убедиться, что он существует, переименовав.apk в.zip и открыв его с помощью 7zip.

У меня есть еще немного кода:

AAssetDir* pAssetDir = AAssetManager_openDir(pAssetManager, sDirectory.c_str());

if (!pAssetDir)
{
    DebugPrint("pAssetDir NULL\n");
    return;
}

const char* pszDir;
while ((pszDir = AAssetDir_getNextFileName(pAssetDir)) != NULL)
{
    DebugPrint(pszDir);
}

AAssetDir_close(pAssetDir);

Этот код ничего не печатает. Другими словами, в каталоге активов не найдено ни одного файла, независимо от того, по каким путям я в него перехожу.

Примечание. DebugPrint - это более симпатичная оболочка для __android_log_print().

2 ответа

Решение

Я передал Activity в AAssetManager_fromJava(), в то время как я должен был передать AssetManager. Если вы передадите неправильный класс в AAssetManager_fromJava(), он потерпит неудачу без печати чего-либо для logcat.

Как получить менеджер активов с JNI:

    JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();

    jobject activity = (jobject)SDL_AndroidGetActivity();

    jclass activity_class = env->GetObjectClass(activity);

    jmethodID activity_class_getAssets = env->GetMethodID(activity_class, "getAssets", "()Landroid/content/res/AssetManager;");
    jobject asset_manager = env->CallObjectMethod(activity, activity_class_getAssets); // activity.getAssets();
    global_asset_manager = env->NewGlobalRef(asset_manager);

    pAssetManager = AAssetManager_fromJava(env, global_asset_manager);

Храните этот указатель менеджера активов где-нибудь и используйте его для всех ваших функций AAssetManager_*().

В моем случае вызов AAssetDir_getNextFileName вернул NULL, потому что я ожидал список каталогов.

Но AAssetDir_getNextFileName не перебирает каталоги. Подробнее см. https://github.com/android/ndk-samples/issues/603 .

Другие вопросы по тегам