ฉันจะเพิ่มทรัพยากร (รูปภาพไฟล์เสียงเฉดสี ฯลฯ ... ) ไปยังโปรเจ็กต์ NDK ด้วย Gradle ได้อย่างไร

Aug 19 2020

ใน codebase เวอร์ชันพีซีฉันมีโครงสร้างไดเร็กทอรีต่อไปนี้:

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

ดังนั้นจากรหัส C ++ ของฉันฉันสามารถขอfopen("resources/images/blah0.png",...)ตัวอย่างเช่น

สำหรับ Android ดูเหมือนว่าจะต้องใช้แทน

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

^ ที่ชี้ไปยังไดเร็กทอรีทรัพยากรเดียวกันที่ระบุไว้ที่ด้านบนสุดของรายการนี้


ฉันต้องทำอย่างไรเพื่อให้แน่ใจว่าลำดับชั้นของทรัพยากรข้างต้นได้รับการถ่ายโอนไปยัง. apk ของฉันเพื่อให้เข้าถึงได้ผ่านทางAAssetManagerตัวอย่างด้านบน


การทดลองเพิ่มเติมบางอย่าง:

ฉันเปลี่ยน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

โอเคปัญหาของฉันคือสามเท่า:

  1. gradle รับผิดชอบการสร้างโครงการ 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. นี่คือโครงร่างของโซลูชัน Pure-C ++ หรือคุณสามารถเรียก Java API (ตามที่นี่ ) ผ่าน JNI