我在我的引擎中使用纯 C++ 在 android 中创建游戏引擎。没有单个 java 文件。基本上它是一个只能存储到外部存储器的游戏。当我通过 adb 手动将我的资产数据移动到我的外部 sd 卡时,游戏已经运行良好且稳定。
adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/
这不是一个好的解决方案,因为它无法交付。因此,我在 Assets 文件夹中有我的资产数据,该文件夹在构建过程中被移动到具有以下结构的 apk 文件中:
资产/数据/MoreFolders/Withsubfolders 资产/数据/EngineData.zip 资产/数据/ScriptData.zip
但我不知道这些文件在文件系统上的什么位置以便在 c++ 代码中访问它们。
所以我试图获取文件目录的路径。由于本机活动状态中的错误,我必须以普通代码检索信息。
// 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() 和 android.os.Environment.getExternalStorageState() 等的 c++ 代码
// 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
但是资产文件夹中没有文件...
我需要访问一个文件夹作为正常工作目录来读取文件。这将是可能的
/mnt/sdcard/Android/data/com.fantasyhaze.rememory/files/Data
但是通过资产管理器将所有数据从资产文件夹(无论它在哪里)移动到这个文件夹,会导致内存消耗加倍。
资产 >1GB 意味着资产 >2GB,这是没有意义的。不仅如此,assert 文件夹似乎不能反复工作,并且仅适用于使用较大 pak 文件时不可能的小数据文件。也许在使用解压缩系统时可以直接从 apk 访问这些文件,然后 uzip 我的资源文件,但因此无论如何我都必须选择 apk 路径。
所以我的问题:
- 文件系统上的 apk 中的 Assets 文件夹在哪里?
- 检索apk位置或可执行文件位置的代码(c ++)是什么
- 我可以使用普通的文件打开方法直接访问它吗?或者只有在我解压后才能访问它。如果我可以在不打开包装的情况下使用它,如何使用?
- 如果安装了 sd 卡,检索信息的代码 (c++) 是什么?
我希望有一个人可以帮助我 :)
编辑:添加缓存目录和包目录代码(以及它的输出路径),为其他需要它的人提供源代码。