Gradle을 사용하여 NDK 프로젝트에 리소스 (이미지, 사운드 파일, 셰이더 등)를 추가하려면 어떻게해야하나요?
이 코드베이스의 PC 버전에서는 다음과 같은 디렉토리 구조가 있습니다.
- 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'
}
}
^이 목록의 맨 위에 설명 된 동일한 리소스 디렉토리를 가리 킵니다.
위의 리소스 계층 구조가 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);
단순히 최상위 디렉토리에서 찾은 파일을 열거합니다. 나는 그것이 디렉토리 에있는 모든 파일 을 열거하는 것을 알아 챘다 . (내 폴더 를 가리키면 아무것도 열거되지 않습니다). 그게 말 그대로 파일 만 가져 오기 때문 인지, gradle 이 파일 만 복사 하는지, 전체 생태계가 플랫 디렉토리에서만 작동하는지, 아니면 무엇인지 모르겠습니다 .some/random/path/on/my/hd
resources
AAssetDir_getNextFileName
srcDirs
AAssetManager
"NDK 앱에 리소스 디렉토리 포함"의 사용 사례를 보여주는 명확한 문서가 없다는 사실에 놀랐습니다. 정말 정상적인 작업처럼 보입니다.
편집 : "cmake가 실행되는 방법"에 대한 설명을 다시 요청했습니다. 내 build.gradle
파일의 일부로 다음 스 니펫이 있습니다.
externalNativeBuild {
cmake {
version "3.18.1"
path "../CMakeLists.txt"
buildStagingDirectory buildDir
}
}
답변
좋아, 내 문제는 세 가지였습니다.
- gradle은 리소스 폴더를 구성하는 내 cmake 프로젝트를 빌드합니다. cmake 프로세스와 자산 패킹 사이에 명시적인 종속성이 없기 때문에 예측할 수없는 시간 (구성이 완료되기 전)에 해당 폴더에서 가져온 것처럼 보입니다. (누군가 이러한 종속성을 지정하는 방법을 알고 있으면 알려주십시오!)
- 내가 할 폴더를 설정할 때
resources
, 그것은 하지 않는 결과root/resources/{images,shaders}
; 결과는root/{images,shaders}
. (누군가가 대신 전자를 지정하는 방법을 알고 있다면 알려주십시오!) AAssetDir_getNextFileName
폴더를 열거 하지 않습니다 . (내가 할 수있는 일은 없다!)
AAssetManager_open(aassman, "/images/blah0.png")
대신 단순히을 사용 하는 것이fopen("resources/images/blah0.png", "r")
좋지만 그것이 너무 중요assets.srcDirs 'build/cmake/release/arm64-v8a
하다면를 제외한 모든 것을 설정 하고 제외 할 수 있습니다"resources"
.다음 은 순수 C ++ 솔루션의 개요입니다. 또는 JNI를 통해 Java API ( 여기 참조 )를 호출 할 수도 있습니다 .