Android NDK编程中不可避免要使用Assets资源,要使用Assets的话,那么必须得先获得C/C++中的AAssetManager对象,获取此对象貌似我还没发现有纯C的方法获得(唉,能力有限啊,大家有方法回复告知啊),只能通过 AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);获得,也就是说, AAssetManager对象的获取是从上层传递下来的,在java中使用如下方法获取:static AssetManager assetManager = getAssets(); ,然后将此assetManager 对象通过JNI传递到底层,代码如下:
JAVA CODE :
AssetManager assetManager = getAssets();
native_method(assetManager);
C/C++ CODE:
jboolean Java_com_XXX_native_method(JNIEnv* env, jclass clazz,jobject assetManager){
//.........................
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
//..............................
}
OK !!
我们获得 AAssetManager对象之后,我们的C/C++语言就可以对此文件夹中的文件为所欲为的操作了
下面是assets_manager.h文件中的内容:
上述函数完成了简单的对assets文件夹下文件的操作,比如打开文件,关闭文件,读取文件/文件长度等,打开文件夹,枚举文件夹等。不过你有没有发现,里面貌似没有Write函数哦。/* Available modes for opening assets */ enum { AASSET_MODE_UNKNOWN = 0, AASSET_MODE_RANDOM = 1, AASSET_MODE_STREAMING = 2, AASSET_MODE_BUFFER = 3 }; /** * 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(). */ AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName); /** * Open an asset. * * The object returned here should be freed by calling AAsset_close(). */ AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode); /** * Iterate over the files in an asset directory. A NULL string is returned * when all the file names have been returned. * * The returned file name is suitable for passing to AAssetManager_open(). * * The string returned here is owned by the AssetDir implementation and is not * guaranteed to remain valid if any other calls are made on this AAssetDir * instance. */ const char* AAssetDir_getNextFileName(AAssetDir* assetDir); /** * Reset the iteration state of AAssetDir_getNextFileName() to the beginning. */ void AAssetDir_rewind(AAssetDir* assetDir); /** * Close an opened AAssetDir, freeing any related resources. */ void AAssetDir_close(AAssetDir* assetDir); /** * Attempt to read 'count' bytes of data from the current offset. * * Returns the number of bytes read, zero on EOF, or < 0 on error. */ int AAsset_read(AAsset* asset, void* buf, size_t count); /** * Seek to the specified offset within the asset data. 'whence' uses the * same constants as lseek()/fseek(). * * Returns the new position on success, or (off_t) -1 on error. */ off_t AAsset_seek(AAsset* asset, off_t offset, int whence); /** * Close the asset, freeing all associated resources. */ void AAsset_close(AAsset* asset); /** * Get a pointer to a buffer holding the entire contents of the assset. * * Returns NULL on failure. */ const void* AAsset_getBuffer(AAsset* asset); /** * Report the total size of the asset data. */ off_t AAsset_getLength(AAsset* asset); /** * Report the total amount of asset data that can be read from the current position. */ off_t AAsset_getRemainingLength(AAsset* asset); /** * Open a new file descriptor that can be used to read the asset data. * * Returns < 0 if direct fd access is not possible (for example, if the asset is * compressed). */ int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength); /** * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not * mmapped). */ int AAsset_isAllocated(AAsset* asset);