首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >直接在c++中访问Android资产数据,无需资产管理器和复制

直接在c++中访问Android资产数据,无需资产管理器和复制
EN

Stack Overflow用户
提问于 2012-04-15 22:18:01
回答 2查看 14.7K关注 0票数 12

我在我的引擎中使用纯C++来在android中创建一个游戏引擎。没有一个java文件。基本上,这是一个游戏,应该只存储到外部内存。当我手动移动我的资产数据通过亚行到我的外部sd卡,游戏已经运行良好和稳定。

代码语言:javascript
复制
adb push ..\..\Bin\Data /sdcard/Android/data/com.fantasyhaze.%SMALL_PACKAGE_NAME%/files/Data/

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

资产/数据/MoreFolders/Withsubfolders资产/Data/EngineData.zip资产/Data/ScriptData.zip

但我不知道这些文件在文件系统中的位置,以便在c++代码中访问它们。

所以我试着找到文件目录的路径。而且,由于本机活动状态中有一个bug,所以我必须在普通代码中检索信息。

代码语言:javascript
复制
// 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.getExternalStorageState() ()和android.os.Environment.getFilesDir等的c++代码

代码语言:javascript
复制
            // 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.faasyhaze.reMemory/file

缓存DIR =/data/data/com.faasyhaze.reMemory/ CACHE

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

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

但资产文件夹里没有文件..。

我需要访问一个文件夹作为正常的工作目录来读取文件。这是有可能的

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

但是,通过资产管理器将所有数据从资产文件夹(无论在何处)移动到此文件夹,会导致内存消耗增加一倍。

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

所以我的问题是:

  1. 文件系统中apk中的资产文件夹在哪里?
  2. 检索apk位置或可执行文件位置的代码(c++)是什么?
  3. 我是否可以使用普通的文件打开方法直接访问它,或者只有当我打开它时才能访问它。如果我不用拆包就能用它,怎么用?
  4. 如果sd卡被挂载,用于检索信息的代码(c++)是什么?

我希望有人能帮我:)

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-15 23:30:21

我贴出了一个答案,而不是将其标记为副本,因为从技术上讲,您要求的细节比我在这里链接的问题/答案中提供的更多。因此,要回答4点中的第一点,请参见使用C++和NativeActivity类获取Android的名称

至于检查是否安装SD卡,这应该是相当简单的。只需尝试打开SDcard上的目录或文件(您知道应该在那里),如果它失败,您就知道SD卡不可用。见检查C中是否存在文件的最佳方法是什么?(跨平台)

票数 2
EN

Stack Overflow用户

发布于 2012-04-16 06:09:25

您可能想看看“扩展文件”(请参阅APK扩展文件 )。

据我所知,这给了您一个自动将资源文件(您的扩展文件)放到“共享存储位置”的系统。

所以我认为这可以解决你重复数据的问题。

还有一个简短的介绍在android开发者博客上发帖

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10166638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档