【发布时间】:2019-09-18 12:46:49
【问题描述】:
我正在尝试为用 C++ 编写的 Android 应用加载一些着色器文件。它使用NativeActivity 和native_app_glue。我很难让 Android Asset 系统按预期工作。
我试过的最简单的情况是:
#include <android_native_app_glue.h>
void android_main(struct android_app *app) {
AAssetDir *dir = AAssetManager_openDir(app->activity->assetManager, "");
if (dir != nullptr) {
LOGD("Opened Dir");
LOGD("Filename: %s", AAssetDir_getNextFileName(dir));
AAssetDir_close(dir);
} else {
LOGE("Failed to open dir");
}
}
AAssetManager_openDir 返回一个有效的 AAssetDir ptr,但 AAssetDir_getNextFileName 总是返回 nullptr。 NDK 的asset_manager.h 标头似乎暗示我的调用应该是绝对有效的。
/**
* Open the named directory within the asset hierarchy. The directory can then
* be inspected with the AAssetDir functions. To open the top-level directory,
* pass in "" as the dirName.
*
* The object returned here should be freed by calling AAssetDir_close().
*/
我似乎也无法通过其他 AAssetManager 调用通过已知文件路径引用任何文件。
AAssetManager_open(app->activity->assetManager, "shaders/triangle.vert.spv", AASSET_MODE_BUFFER);
即使在我的 APK 中我可以清楚地看到 assets/shaders 中正确存在的文件,也会失败。我在 Logcat 中的应用中找不到任何相关错误。我在 Android 权限文档中找不到任何关于需要某种权限才能读取内部资产的相关内容。
我目前正在使用最新的 NDK r19 针对 Android 28 进行构建。这是我目前正在使用的 android-sdk 软件包集:
Installed packages:
Path | Version | Description | Location
------- | ------- | ------- | -------
build-tools;27.0.3 | 27.0.3 | Android SDK Build-Tools 27.0.3 | build-tools\27.0.3\
emulator | 28.0.25 | Android Emulator | emulator\
ndk-bundle | 19.2.5345600 | NDK | ndk-bundle\
patcher;v4 | 1 | SDK Patch Applier v4 | patcher\v4\
platform-tools | 28.0.2 | Android SDK Platform-Tools | platform-tools\
platforms;android-21 | 2 | Android SDK Platform 21 | platforms\android-21\
platforms;android-28 | 6 | Android SDK Platform 28 | platforms\android-28\
tools | 26.0.1 | Android SDK Tools 26.0.1 | tools\
我目前通过部署到带有最新补丁的 Pixel 2 XL 进行测试。
我是否将资产放在错误的文件夹中?我错过了一些最近的权限更改吗?
编辑#1:
做了更多调查。在我的 APK 资产目录的根目录下放置了一个 test.txt,因此 APK 现在有 assets/test.txt。我试过打开这个文件的句柄:
AAsset *asset = AAssetManager_open(app->activity->assetManager, "test.txt",
AASSET_MODE_BUFFER);
if (asset != nullptr) {
LOGD("Opened test file");
AAsset_close(asset);
} else {
LOGE("Failed to open test file");
}
应用程序将“无法打开测试文件”打印到 Logcat。仍然不知道是什么原因造成的。
编辑#2:回复第一个答案。
按照建议尝试更完整的代码示例不会产生任何新结果:
#include <android_native_app_glue.h>
void android_main(struct android_app *app) {
AAssetManager *assetManager = app->activity->assetManager;
if (assetManager != nullptr) {
AAssetDir *assetDir = AAssetManager_openDir(assetManager, "");
if (assetDir != nullptr) {
uint32_t fileOpenedCounter = 0;
const char *filename = (const char *)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset *asset =
AAssetManager_open(assetManager, filename, AASSET_MODE_BUFFER);
if (asset != nullptr) {
LOGD("Opened test file");
fileOpenedCounter++;
char buf[1024];
int nb_read = 0;
while ((nb_read = AAsset_read(asset, buf, 27)) > 0) {
LOGD("buf: %s", buf);
}
AAsset_close(asset);
} else {
LOGE("Failed to open test file");
}
}
LOGD("Opened %d files from root directory", fileOpenedCounter);
AAssetDir_close(assetDir);
} else {
LOGE("Failed to open root directory");
}
} else {
LOGE("Asset Manager was invalid");
}
}
我从 Logcat 得到的只是调试日志:“从根目录打开 0 个文件”。这似乎意味着我拥有的 AAssetManager 指针是有效的,它可以 打开 目录,但找不到任何文件或子目录。
【问题讨论】:
标签: android c++ android-ndk