Bagaimana cara menambahkan sumber daya (gambar, file suara, shader, dll…) ke proyek NDK dengan Gradle?
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, file
akan 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 AAssetManager
cuplikan di atas?
Beberapa eksperimen tambahan:
Aku mengubah assets.srcDirs
jalur 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 resources
folder saya , itu tidak menyebutkan apa-apa). Saya tidak tahu apakah itu karena AAssetDir_getNextFileName
secara harfiah hanya mendapatkan file , atau jika gradle srcDirs
hanya menyalin file, atau jika seluruh AAssetManager
ekosistem 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.gradle
file saya , cuplikan berikut:
externalNativeBuild {
cmake {
version "3.18.1"
path "../CMakeLists.txt"
buildStagingDirectory buildDir
}
}
Jawaban
Ok jadi masalah saya tiga kali lipat:
- 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!)
- ketika saya menyetel foldernya menjadi
resources
, itu tidak menghasilkanroot/resources/{images,shaders}
; itu menghasilkanroot/{images,shaders}
. (Jika seseorang tahu bagaimana menentukan untuk melakukan yang pertama, tolong beri tahu saya!) AAssetDir_getNextFileName
tidak menghitung folder. (Tidak ada yang bisa saya lakukan tentang ini!)
Saya akan menyarankan untuk hanya menggunakan
AAssetManager_open(aassman, "/images/blah0.png")
alih-alihfopen("resources/images/blah0.png", "r")
, tetapi jika itu sangat penting bagi Anda, Anda dapat mengaturassets.srcDirs 'build/cmake/release/arm64-v8a
dan mengecualikan semuanya kecuali"resources"
.Berikut adalah garis besar solusi murni-C ++. Atau, Anda juga bisa memanggil Java API (seperti di sini ) melalui JNI.