Gradle ile bir NDK projesine nasıl kaynak (resimler, ses dosyaları, gölgelendiriciler vb.) Ekleyebilirim?

Aug 19 2020

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, filegeliyor nullptro 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

1 Phildo Aug 18 2020 at 23:23

Ok so my problem was three fold:

  1. 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!)
  2. when I set the folder to be resources, it doesn't result in root/resources/{images,shaders}; it results in root/{images,shaders}. (If someone knows how to specify to instead do the former, please let me know!)
  3. AAssetDir_getNextFileName does not enumerate folders. (There's nothing I can do about this!)
1 AlexCohn Aug 24 2020 at 15:54
  1. I would suggest to simply use AAssetManager_open(aassman, "/images/blah0.png") instead of fopen("resources/images/blah0.png", "r"), but if it's so important to you, you can set assets.srcDirs 'build/cmake/release/arm64-v8a and exclude everything except "resources".

  2. Here is an outline of a pure-C++ solution. Alternatively, you can also call the Java API (as here) via JNI.