gpt4 book ai didi

android - 无需 Asset Manager 和复制,直接在 C++ 中访问 Android APK Asset 数据

转载 作者:可可西里 更新时间:2023-11-01 15:24:58 27 4
gpt4 key购买 nike

我在我的引擎中使用纯 C++ 在 android 中创建游戏引擎。没有单个 java 文件。基本上这是一款只能存储到外部存储器的游戏。当我通过 adb 手动将我的 Assets 数据移动到我的外部 SD 卡时,游戏运行良好且稳定。

adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/

这不是一个好的解决方案,因为它无法交付。因此我的 Assets 数据在 Assets 文件夹中它在构建过程中被移动到具有以下结构的 apk 文件中:

Assets /数据/MoreFolders/Withsubfolders Assets /数据/EngineData.zip Assets /数据/ScriptData.zip

但我不知道这些文件在文件系统中的什么位置,无法用 C++ 代码访问它们。

所以我试图获取文件目录的路径。并且由于 native Activity 状态中的错误我必须以正常代码检索信息。

// bug in 2.3 internalDataPath / externalDataPath = null using jni code instead
//FHZ_PRINTF("INTERNAL inter PATH = %s\n", state->activity->internalDataPath);
//FHZ_PRINTF("EXTERNAL inter PATH = %s\n", state->activity->externalDataPath);

相当于 android.os.Environment.getFilesDir() 的 C++ 代码和 android.os.Environment.getExternalStorageState() 等等

            // getPath() - java
JNIEnv *jni_env = Core::HAZEOS::GetJNIEnv();
jclass cls_Env = jni_env->FindClass("android/app/NativeActivity");
jmethodID mid_getExtStorage = jni_env->GetMethodID(cls_Env, "getFilesDir","()Ljava/io/File;");
jobject obj_File = jni_env->CallObjectMethod( gstate->activity->clazz, mid_getExtStorage);
jclass cls_File = jni_env->FindClass("java/io/File");
jmethodID mid_getPath = jni_env->GetMethodID(cls_File, "getPath","()Ljava/lang/String;");
jstring obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
const char* path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("INTERNAL PATH = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);

// getCacheDir() - java
mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getCacheDir", "()Ljava/io/File;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL);
cls_File = jni_env->FindClass("java/io/File");
mid_getPath = jni_env->GetMethodID(cls_File, "getAbsolutePath", "()Ljava/lang/String;");
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("CACHE DIR = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);

// getExternalFilesDir() - java
mid_getExtStorage = jni_env->GetMethodID( cls_Env,"getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getExtStorage, NULL);
cls_File = jni_env->FindClass("java/io/File");
mid_getPath = jni_env->GetMethodID(cls_File, "getPath", "()Ljava/lang/String;");
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("EXTERNAL PATH = %s\n", path);
jni_env->ReleaseStringUTFChars(obj_Path, path);

//getPackageCodePath() - java
mid_getPath = jni_env->GetMethodID(cls_Env, "getPackageCodePath", "()Ljava/lang/String;");
obj_File = jni_env->CallObjectMethod(gstate->activity->clazz, mid_getPath);
obj_Path = (jstring) jni_env->CallObjectMethod(obj_File, mid_getPath);
path = jni_env->GetStringUTFChars(obj_Path, NULL);
FHZ_PRINTF("Looked up package code path = %s\n", path);

效果很好,结果是

内部路径 =/data/data/com.fantasyhaze.rememory/files

缓存目录 =/data/data/com.fantasyhaze.rememory/cache

外部路径 =/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files

查找包代码路径=/mnt/asec/com.fantasyhaze.rememory-2/pkg.apk

但是 Assets 文件夹中没有文件...

我需要访问一个文件夹作为正常工作目录来读取文件。这在

中是可能的

/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files/Data

但是通过 Assets 管理器将所有数据从 Assets 文件夹(无论它在哪里)移动到这个文件夹,会导致内存消耗加倍。

Assets >1GB 意味着 Assets >2GB,这没有意义。不仅如此,assert 文件夹似乎不能递归工作,而且只能用于小数据文件这在使用更大的 pak 文件时是不可能的。也许这些文件可以在使用时直接从apk访问解压系统,然后解压我的资源文件,但因此我必须选择 apk 路径。

所以我的问题:

  1. apk 中的 Assets 文件夹在文件系统中的什么位置?
  2. 检索 apk 位置或可执行文件位置的代码 (c++) 是什么
  3. 我可以使用普通文件打开方法直接访问它还是只有在解压缩后才能访问它。如果我可以不打开包装就可以使用它,怎么样?
  4. 如果安装了 sd 卡,检索信息的代码 (c++) 是什么?

我希望有人能帮助我:)

编辑:添加缓存目录和包目录代码(及其输出路径),为其他需要它的人提供源。

最佳答案

我发布了一个答案,而不是将其标记为重复,因为从技术上讲,您要求提供的详细信息比我将在此处链接的问题/答案中提供的更多。因此,要回答您的 4 点中的第一点,请参阅 Obtaining the name of an Android APK using C++ and the NativeActivity class .

至于检查SD卡是否挂载,应该比较简单。只需尝试打开 SD 卡上的目录或文件(您知道应该在那里),如果失败,您就知道 SD 卡不可用。参见 What's the best way to check if a file exists in C? (cross platform) .

关于android - 无需 Asset Manager 和复制,直接在 C++ 中访问 Android APK Asset 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10166638/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com