Как я могу добавить ресурсы (изображения, звуковые файлы, шейдеры и т. Д.) В проект NDK с помощью Gradle?
В версии этой кодовой базы для ПК у меня просто следующая структура каталогов:
- myApp.exe
- resources
- - images
- - - blah0.png
- - - blah1.png
- - shaders
- - - blahA.spv
- - - blahB.spv
Итак, из моего кода на C ++ я могу fopen("resources/images/blah0.png",...)
, например, просто запросить .
В Android вместо этого требуется
#include <android/native_activity.h>
...
AAsset* file = AAssetManager_open(aassman, "resources/images/blah0.png", AASSET_MODE_STREAMING);
size_t len = AAsset_getRemainingLength64(file);
char *buff = malloc(len);
size_t read = AAsset_read(file, buff, len);
AAsset_close(file);
К сожалению, file
он появляется nullptr
, вероятно, потому, что не может найти это дерево ресурсов.
В моем скрипте build.gradle есть следующий фрагмент:
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
assets.srcDirs 'build/cmake/release/arm64-v8a/resources'
}
}
^ Это указывает на тот же каталог ресурсов, указанный в верхней части этого списка.
Что мне нужно сделать, чтобы указанная выше иерархия ресурсов была просто перенесена в мой .apk, чтобы к ней можно было получить доступ через приведенный AAssetManager
выше фрагмент?
Некоторые дополнительные эксперименты:
Я изменил assets.srcDirs
путь some/random/path/on/my/hd
и побежал
AAssetDir *rootAssets = AAssetManager_openDir(aassman, "");
const char *f = AAssetDir_getNextFileName(rootAssets);
while(f)
{
print(f);
f = AAssetDir_getNextFileName(rootAssets);
}
AAssetDir_close(rootAssets);
который просто перечисляет найденные файлы в верхнем каталоге. Я заметил , что он перечислил все файлы , которые были в some/random/path/on/my/hd
, но ни один из каталогов . (Когда я указываю его на свою resources
папку, он ничего не перечисляет). Я понятия не имею, потому что AAssetDir_getNextFileName
буквально только получает файлы , или если gradle srcDirs
только копирует файлы, или вся AAssetManager
экосистема работает только с плоскими каталогами, или что-то еще.
Я удивлен, что нет четкой документации, показывающей вариант использования «включение каталога ресурсов в ваше приложение NDK», поскольку это кажется действительно нормальным делом.
edit: Меня попросили пояснить, как запускается cmake. В моем build.gradle
файле есть следующий фрагмент:
externalNativeBuild {
cmake {
version "3.18.1"
path "../CMakeLists.txt"
buildStagingDirectory buildDir
}
}
Ответы
Итак, моя проблема была трехкратной:
- gradle отвечает за создание моего проекта cmake, который создает папку ресурсов. поскольку нет явной зависимости между процессом cmake и упаковкой ресурсов, казалось, что он извлекался из этой папки в непредсказуемое время (возможно, до того, как его построение было завершено). (Если кто-то знает, как указать такую зависимость, дайте мне знать!)
- когда я устанавливаю папку
resources
, это не приводит кroot/resources/{images,shaders}
; это приводит кroot/{images,shaders}
. (Если кто-то знает, как указать первое, пожалуйста, дайте мне знать!) AAssetDir_getNextFileName
не перечисляет папки. (Я ничего не могу с этим поделать!)
Я бы предложил просто использовать
AAssetManager_open(aassman, "/images/blah0.png")
вместоfopen("resources/images/blah0.png", "r")
, но если это так важно для вас, вы можете установитьassets.srcDirs 'build/cmake/release/arm64-v8a
и исключить все, кроме"resources"
.Вот схема решения на чистом C ++. Кроме того, вы также можете вызвать Java API (как здесь ) через JNI.