Gradle ile bir NDK projesine nasıl kaynak (resimler, ses dosyaları, gölgelendiriciler vb.) Ekleyebilirim?
Bu kod tabanının PC sürümünde, aşağıdaki dizin yapısına sahibim:
- myApp.exe
- resources
- - images
- - - blah0.png
- - - blah1.png
- - shaders
- - - blahA.spv
- - - blahB.spv
Yani, C ++ kodumdan fopen("resources/images/blah0.png",...)
örneğin basitçe talep edebilirim .
Android ile bunun yerine,
#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);
Ne yazık ki, file
geliyor nullptr
o kaynaklar ağacını bulamıyor olasılıkla çünkü.
My build.gradle script has the following snippet:
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
assets.srcDirs 'build/cmake/release/arm64-v8a/resources'
}
}
^ That points to the same resources directory outlined at the top of this list.
What do I need to do to ensure that the above resources hierarchy gets simply transferred into my .apk such that it might be accessed via the AAssetManager
snippet above?
Some additional experimentation:
I altered the assets.srcDirs
path to some/random/path/on/my/hd
, and then ran
AAssetDir *rootAssets = AAssetManager_openDir(aassman, "");
const char *f = AAssetDir_getNextFileName(rootAssets);
while(f)
{
print(f);
f = AAssetDir_getNextFileName(rootAssets);
}
AAssetDir_close(rootAssets);
which simply enumerates the found files in the top directory. I noticed that it enumerated all of the files which were in some/random/path/on/my/hd
, but none of the directories. (When I point it to my resources
folder, it enumerates nothing). I have no idea if that's because AAssetDir_getNextFileName
literally only gets files, or if gradle's srcDirs
only copies files, or if the whole AAssetManager
ecosystem only works on flat directories, or what.
I'm astounded that there isn't clear documentation showing the use case of "including a resources directory with your NDK app", as that seems like a really normal thing to need to do.
edit: I was asked for clarification re: "how cmake is run". I have as part of my build.gradle
file, the following snippet:
externalNativeBuild {
cmake {
version "3.18.1"
path "../CMakeLists.txt"
buildStagingDirectory buildDir
}
}
Yanıtlar
Ok so my problem was three fold:
- gradle is in charge of building my cmake project which constructs the resources folder. because there is no explicit dependency given between the cmake process and the packing of assets, it seemed to have been pulling from that folder at an unpredictable time (potentially before its construction is finished). (If someone knows how to specify such a dependency, please let me know!)
- when I set the folder to be
resources
, it doesn't result inroot/resources/{images,shaders}
; it results inroot/{images,shaders}
. (If someone knows how to specify to instead do the former, please let me know!) AAssetDir_getNextFileName
does not enumerate folders. (There's nothing I can do about this!)
I would suggest to simply use
AAssetManager_open(aassman, "/images/blah0.png")
instead offopen("resources/images/blah0.png", "r")
, but if it's so important to you, you can setassets.srcDirs 'build/cmake/release/arm64-v8a
and exclude everything except"resources"
.Here is an outline of a pure-C++ solution. Alternatively, you can also call the Java API (as here) via JNI.