之前提到在Android平台下, 有以下两个问题需要解决:
一: 在Android上如何读写文件? 三维程序需要载入模型, 纹理, 着色器脚本等数据, 如何读写这些文件?
二: 如何把第三方库移植到Android平台上, 可以使用CMake? 还是为其编写Android.mk
首先看看使用在jni层如何读写文件的问题:
从数据存放位置来分, 读写文件可以分为两类, 第一类读取assets文件夹内的文件, 第二类是读取sd卡内的文件。 相比较而言, 读取sd卡内的文件要容易一些(可以看成是读取某磁盘目录下的文件), 直接用标准库中的IO函数即可读取。 但是读取assets下的文件就要用到专门的函数了。
读取asset下文件的方法:
(1) :需要头文件: #include <android_native_app_glue.h>
(2): AAssetManager* assetManager = this->mActivity->assetManager; //获取assetManager
(3): AAssetManager_open(...) // 打开文件
(4):AAsset_getBuffer(...) //获取文件内容
(5): AAsset_getLength(...) //获取文件长度
下面看下代码:
#pragma once #include <jni.h> #include <vector> #include <string> #include <android_native_app_glue.h> #include "AndroidLog.h" class AndroidIO { public: AndroidIO(ANativeActivity* activity); bool readText(const char* filename, std::vector<unsigned char>* buffer); ~AndroidIO(); private: ANativeActivity* mActivity; mutable pthread_mutex_t mMutex; };
#include "AndroidIO.h" #include <fstream> #include <iostream> AndroidIO::AndroidIO(ANativeActivity* activity) { pthread_mutex_init(&mMutex, NULL); pthread_mutex_lock(&mMutex); this->mActivity = activity; pthread_mutex_unlock(&mMutex); } bool AndroidIO::readText(const char* filename, std::vector<unsigned char> *buffer) { pthread_mutex_lock(&mMutex); std::ifstream f(filename, std::ios::binary ); if(f) { LOGI( "reading sdcard:%s", filename ); f.seekg( 0, std::ifstream::end ); int32_t fileSize = f.tellg(); f.seekg( 0, std::ifstream::beg ); buffer->reserve( fileSize ); buffer->assign( std::istreambuf_iterator<char>( f ), std::istreambuf_iterator<char>() ); f.close(); pthread_mutex_unlock( &mMutex ); return true; } else { LOGI( "reading assest:%s", filename ); AAssetManager* assetManager = this->mActivity->assetManager; AAsset* assetFile = AAssetManager_open( assetManager, filename, AASSET_MODE_BUFFER ); if( !assetFile ) { pthread_mutex_unlock( &mMutex ); return false; } uint8_t* data = (uint8_t*) AAsset_getBuffer( assetFile ); int32_t size = AAsset_getLength( assetFile ); if( data == NULL ) { AAsset_close( assetFile ); LOGI( "Failed to load:%s", filename ); pthread_mutex_unlock( &mMutex ); return false; } buffer->reserve( size ); buffer->assign( data, data + size ); AAsset_close( assetFile ); pthread_mutex_unlock( &mMutex ); return true; } } AndroidIO::~AndroidIO() { pthread_mutex_destroy(&mMutex); }
为了验证读取文件功能, 我把shader文件分别放到assets文件夹下, 和sd卡上, 下面是运行结果:
下面看看第三方的C++库如何移植到Android:
作者:zg260 发表于2017/7/18 9:07:00 原文链接
阅读:19 评论:0 查看评论