Gradleを使用してNDKプロジェクトにリソース(画像、サウンドファイル、シェーダーなど)を追加するにはどうすればよいですか?

Aug 19 2020

このコードベースのPCバージョンでは、次のディレクトリ構造になっています。

 - myApp.exe
 - resources
 - - images
 - - - blah0.png
 - - - blah1.png
 - - shaders
 - - - blahA.spv
 - - - blahB.spv

したがって、C ++コードから、fopen("resources/images/blah0.png",...)たとえば、単純に要求できます。

アンドロイドでは、代わりにそれが必要とされるようです

#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'
    }
  }

^これは、このリストの上部に概説されているのと同じリソースディレクトリを指しています。


AAssetManager上記のスニペットを介してアクセスできるように、上記のリソース階層が単純に.apkに転送されるようにするには、何をする必要がありますか?


いくつかの追加の実験:

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アプリにリソースディレクトリを含める」のユースケースを示す明確なドキュメントがないことに驚いています。これは、本当に普通のことのように思えます。


編集:「cmakeの実行方法」について説明を求められました。build.gradleファイルの一部として、次のスニペットがあります。

  externalNativeBuild {
    cmake {
      version "3.18.1"
      path "../CMakeLists.txt"
      buildStagingDirectory buildDir
    }
  }

回答

1 Phildo Aug 18 2020 at 23:23

さて、私の問題は3つありました。

  1. gradleは、resourcesフォルダーを構築するcmakeプロジェクトの構築を担当しています。cmakeプロセスとアセットのパッキングの間に明示的な依存関係が与えられていないため、予測できない時間(潜在的には構築が完了する前)にそのフォルダーからプルされているように見えました。(誰かがそのような依存関係を指定する方法を知っているなら、私に知らせてください!)
  2. 私がするフォルダを設定するときresources、それはしないにつながりますroot/resources/{images,shaders}。結果はroot/{images,shaders}。(誰かが前者を代わりに行うように指定する方法を知っているなら、私に知らせてください!)
  3. AAssetDir_getNextFileName フォルダを列挙しません。(これについて私にできることは何もありません!)
1 AlexCohn Aug 24 2020 at 15:54
  1. AAssetManager_open(aassman, "/images/blah0.png")代わりに単に使用することをお勧めしますfopen("resources/images/blah0.png", "r")が、それが非常に重要な場合は、をassets.srcDirs 'build/cmake/release/arm64-v8a除くすべてを設定および除外できます"resources"

  2. これが純粋なC ++ソリューションの概要です。または、JNIを介して(ここにあるように)JavaAPIを呼び出すこともできます。