Bagaimana cara menambahkan sumber daya (gambar, file suara, shader, dll…) ke proyek NDK dengan Gradle?

Aug 19 2020

Dalam versi PC dari basis kode ini, saya hanya memiliki struktur direktori berikut:

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

Jadi, dari kode C ++ saya, saya cukup meminta fopen("resources/images/blah0.png",...), misalnya.

Dengan android, tampaknya itu malah diwajibkan

#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);

Sayangnya, fileakan datang nullptr, kemungkinan karena tidak dapat menemukan pohon sumber daya itu.

Skrip build.gradle saya memiliki cuplikan berikut:

  sourceSets {
    main {
      manifest.srcFile 'AndroidManifest.xml'
      assets.srcDirs 'build/cmake/release/arm64-v8a/resources'
    }
  }

^ Itu menunjuk ke direktori sumber daya yang sama yang diuraikan di bagian atas daftar ini.


Apa yang harus saya lakukan untuk memastikan bahwa hierarki sumber daya di atas ditransfer begitu saja ke .apk saya sehingga dapat diakses melalui AAssetManagercuplikan di atas?


Beberapa eksperimen tambahan:

Aku mengubah assets.srcDirsjalur ke some/random/path/on/my/hd, lalu lari

  AAssetDir *rootAssets = AAssetManager_openDir(aassman, "");
  const char *f = AAssetDir_getNextFileName(rootAssets);
  while(f)
  {
    print(f);
    f = AAssetDir_getNextFileName(rootAssets);
  }
  AAssetDir_close(rootAssets);

yang hanya menyebutkan file yang ditemukan di direktori teratas. Saya perhatikan bahwa itu menghitung semua file yang ada di some/random/path/on/my/hd, tetapi tidak ada direktori . (Ketika saya mengarahkannya ke resourcesfolder saya , itu tidak menyebutkan apa-apa). Saya tidak tahu apakah itu karena AAssetDir_getNextFileNamesecara harfiah hanya mendapatkan file , atau jika gradle srcDirshanya menyalin file, atau jika seluruh AAssetManagerekosistem hanya berfungsi pada direktori datar, atau apa.

Saya heran karena tidak ada dokumentasi jelas yang menunjukkan kasus penggunaan "termasuk direktori resource dengan aplikasi NDK Anda", karena hal itu tampaknya perlu dilakukan.


edit: Saya dimintai klarifikasi ulang: "bagaimana cmake dijalankan". Saya memiliki sebagai bagian dari build.gradlefile saya , cuplikan berikut:

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

Jawaban

1 Phildo Aug 18 2020 at 23:23

Ok jadi masalah saya tiga kali lipat:

  1. gradle bertanggung jawab membangun proyek cmake saya yang membangun folder sumber daya. karena tidak ada ketergantungan eksplisit yang diberikan antara proses cmake dan pengemasan aset, tampaknya telah menarik dari folder itu pada waktu yang tidak dapat diprediksi (berpotensi sebelum pembangunannya selesai). (Jika seseorang tahu cara menentukan ketergantungan seperti itu, beri tahu saya!)
  2. ketika saya menyetel foldernya menjadi resources, itu tidak menghasilkan root/resources/{images,shaders}; itu menghasilkan root/{images,shaders}. (Jika seseorang tahu bagaimana menentukan untuk melakukan yang pertama, tolong beri tahu saya!)
  3. AAssetDir_getNextFileName tidak menghitung folder. (Tidak ada yang bisa saya lakukan tentang ini!)
1 AlexCohn Aug 24 2020 at 15:54
  1. Saya akan menyarankan untuk hanya menggunakan AAssetManager_open(aassman, "/images/blah0.png")alih-alih fopen("resources/images/blah0.png", "r"), tetapi jika itu sangat penting bagi Anda, Anda dapat mengatur assets.srcDirs 'build/cmake/release/arm64-v8adan mengecualikan semuanya kecuali "resources".

  2. Berikut adalah garis besar solusi murni-C ++. Atau, Anda juga bisa memanggil Java API (seperti di sini ) melalui JNI.