android常见问题之jni读取assets资源文件

转载 2012年03月31日 08:46:11

assets目录底下的文件会被打包到一个apk文件里,这些资源在安装时他们并没被解压,使用时是直接从apk中读取的。这里介绍下怎么在jni内使用 ndk自带api的接口函数读取assets资源文件,和libzip库函数的使用,可以用来读创建修改压缩文档,这里也是以读取apk安装包内的资源文 件为例。

1 用ndk自带的接口函数读apk包

从2.3开始提供这些接口函数,具体看头文件assert.h android/asset_manager.h android/asset_manager_jni.h,可以参考ndk自带例子中samples/native-audio/ jni/native-audio-jni.c。

  1. /************************************** 
  2. * Function Name  : java_com_fontlose_ReadAssets_readFromAssets 
  3. * Description    : void  readFromAssets(AssetManager ass,String filename); 
  4. * Input          : AssetManager对象 filename资源名 
  5. * Output         : None 
  6. * Return         : None 
  7. ***************************************/  
  8. void  Java_com_fontlose_ReadAssets_readFromAssets(JNIEnv* env,jclass tis
  9. ,jobject assetManager,jstring filename) 
  10.    LOGI("ReadAssets");  
  11.    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager); 
  12.    if(mgr==NULL) 
  13.    { 
  14.       LOGI(" %s","AAssetManager==NULL"); 
  15.       return ; 
  16.    } 
  17.   
  18.     /*获取文件名并打开*/ 
  19.    jboolean iscopy; 
  20.    const char *mfile = (*env)->GetStringUTFChars(env, filename, &iscopy); 
  21.    AAsset* asset = AAssetManager_open(mgr, mfile,AASSET_MODE_UNKNOWN); 
  22.    (*env)->ReleaseStringUTFChars(env, filename, mfile); 
  23.    if(asset==NULL) 
  24.    { 
  25.       LOGI(" %s","asset==NULL"); 
  26.       return ; 
  27.    } 
  28.    /*获取文件大小*/ 
  29.    off_t bufferSize = AAsset_getLength(asset); 
  30.    LOGI("file size         : %d\n",bufferSize); 
  31.    char *buffer=(char *)malloc(bufferSize+1); 
  32.    buffer[bufferSize]=0; 
  33.    int numBytesRead = AAsset_read(asset, buffer, bufferSize); 
  34.    LOGI(": %s",buffer); 
  35.    free(buffer); 
  36.     /*关闭文件*/ 
  37.    AAsset_close(asset); 

在应用程序内使用定义和使用如下

  1. public native void  readFromAssets(AssetManager ass,String filename);  

readFromAssets(getAssets(),"log.txt");

logcat测试结果

12-15 15:27:33.290: INFO/ReadAssets(3570): ReadAssets
12-15 15:27:33.290: INFO/ReadAssets(3570): file size         : 138
12-15 15:27:33.290: INFO/ReadAssets(3570): : 。。。。。。。。。。。。。。。。
12-15 15:27:33.290: INFO/ReadAssets(3570): 这个例子从jni读取assets内文件
12-15 15:27:33.290: INFO/ReadAssets(3570): 。。。。。。。。。。。。。。。。

2 使用libzip库读apk包
     libzip 使用 C 库来 读创建修改压缩文档,关于libzip在andorid的移植可以参考老外做的android-ndk-assets.zip这个工程,已在NDK下可以编译了,修改下编译生成libzip.so,利用libzip.so和zip.h建立工程,使用libzip还可以读取apk包内其他压缩文件如AndroidManifest.xml布局xml等。

  1. /************************************* 
  2. * Function Name  : java_com_fontlose_ReadAssets_readFromAssetsLibzip 
  3. * Description    : void readFromAssetsLibzip(String apkpath,String filename); 
  4. * Input          : apkpath路径 filename 资源名 
  5. * Output         : None 
  6. * Return         : None 
  7. **************************************/  
  8. void  Java_com_fontlose_ReadAssets_readFromAssetsLibzip(JNIEnv* env
  9. ,jclass tis,jstring assetpath,jstring filename) 
  10.    LOGI("ReadAssets");  
  11.   int i=0; 
  12.    jboolean iscopy; 
  13.    const char *mpath = (*env)->GetStringUTFChars(env, assetpath, &iscopy); 
  14.    struct zip* apkArchive=zip_open(mpath, 0, NULL);; 
  15.    (*env)->ReleaseStringUTFChars(env, filename, mpath); 
  16.  
  17.    struct zip_stat fstat; 
  18.    zip_stat_init(&fstat); 
  19.  
  20.    int numFiles = zip_get_num_files(apkArchive); 
  21.    LOGI("File numFiles %i \n",numFiles); 
  22.    for (i=0; i<numFiles; i++) { 
  23.      const char* name = zip_get_name(apkArchive, i, 0); 
  24.      
  25.      if (name == NULL) { 
  26.       LOGE("Error reading zip file name at index %i : %s", zip_strerror(apkArchive)); 
  27.       return
  28.     } 
  29.     
  30.     zip_stat(apkArchive,name,0,&fstat); 
  31.     LOGI("File %i:%s Size1: %d Size2: %d", i,fstat.name,fstat.size ,fstat.comp_size)  ; 
  32.    } 
  33.  
  34.    const char *fname = (*env)->GetStringUTFChars(env, filename, &iscopy); 
  35.    struct zip_file* file = zip_fopen(apkArchive, fname, 0); 
  36.   
  37.    if (!file) { 
  38.      LOGE("Error opening %s from APK", fname); 
  39.      return
  40.     } 
  41.  
  42.    zip_stat(apkArchive,fname,0,&fstat); 
  43.    (*env)->ReleaseStringUTFChars(env, filename, fname); 
  44.    char *buffer=(char *)malloc(fstat.size+1); 
  45.    buffer[fstat.size]=0; 
  46.    int numBytesRead =  zip_fread(file, buffer,fstat.size);; 
  47.    LOGI(": %s\n",buffer); 
  48.    free(buffer); 
  49.    zip_fclose(file); 
  50.    zip_close(apkArchive); 

在应用程序内使用定义和使用如下

  1. public native void  readFromAssetsLibzip(String apkpath,String filename); 

readFromAssetsLibzip(getPackageResourcePath(),"assets/log.txt");

logcat测试结果

12-15 15:28:03.430: INFO/ReadAssets(3570): ReadAssets
12-15 15:28:03.440: INFO/ReadAssets(3570): File numFiles 14
12-15 15:28:03.440: INFO/ReadAssets(3570): File 0:assets/log 2.txt Size1: 138 Size2: 55
12-15 15:28:03.440: INFO/ReadAssets(3570): File 1:assets/log.txt Size1: 138 Size2: 55
12-15 15:28:03.440: INFO/ReadAssets(3570): File 2:res/layout/main.xml Size1: 956 Size2: 337
12-15 15:28:03.440: INFO/ReadAssets(3570): File 3:AndroidManifest.xml Size1: 1348 Size2: 531
12-15 15:28:03.440: INFO/ReadAssets(3570): File 4:resources.arsc Size1: 1480 Size2: 1480
12-15 15:28:03.440: INFO/ReadAssets(3570): File 5:res/drawable-hdpi/icon.png Size1: 3966 Size2: 3966
12-15 15:28:03.440: INFO/ReadAssets(3570): File 6:res/drawable-ldpi/icon.png Size1: 1537 Size2: 1537
12-15 15:28:03.440: INFO/ReadAssets(3570): File 7:res/drawable-mdpi/icon.png Size1: 2200 Size2: 2200
12-15 15:28:03.440: INFO/ReadAssets(3570): File 8:classes.dex Size1: 3468 Size2: 1680
12-15 15:28:03.440: INFO/ReadAssets(3570): File 9:lib/armeabi/libzip.so Size1: 217246 Size2: 46140
12-15 15:28:03.440: INFO/ReadAssets(3570): File 10:lib/armeabi/libreadres.so Size1: 3820 Size2: 1779
12-15 15:28:03.440: INFO/ReadAssets(3570): File 11:META-INF/MANIFEST.MF Size1: 852 Size2: 443
12-15 15:28:03.440: INFO/ReadAssets(3570): File 12:META-INF/CERT.SF Size1: 905 Size2: 487
12-15 15:28:03.440: INFO/ReadAssets(3570): File 13:META-INF/CERT.RSA Size1: 776 Size2: 606
12-15 15:28:03.440: INFO/ReadAssets(3570): : 。。。。。。。。。。。。。。。。
12-15 15:28:03.440: INFO/ReadAssets(3570): 这个例子从jni读取assets内文件
12-15 15:28:03.440: INFO/ReadAssets(3570): 。。。。。。。。。。。。。。。。

上面例子使用android.mk如下

 

  1. LOCAL_PATH := $(call my-dir) 
  2. include $(CLEAR_VARS) 
  3. LOCAL_MODULE    := readres 
  4. LOCAL_SRC_FILES := readres.c  
  5. LOCAL_C_INCLUDES+= /opt/android-ndk-r5/platforms/android-9/arch-arm/usr/include 
  6. LOCAL_LDLIBS    += -L/opt/android-ndk-r5/platforms/android-9/arch-arm/usr/lib/ -llog 
  7. LOCAL_LDLIBS    += -landroid 
  8. LOCAL_LDLIBS    += -lz  
  9. LOCAL_LDLIBS    += -L$(LOCAL_PATH) -lzip 
  10. include $(BUILD_SHARED_LIBRARY) 

转自:http://www.rosoo.net/a/201112/15459.html

相关文章推荐

android JNI使用AAssetManager读取asset目录内容

JNI读取安卓asset下的文件需要使用到NDK目录下的asset_manager_jni.h和asset_manager.h提供的接口。 1.从java端使用getAssets...

Android ndk下用AssetManager读取assets的资源

【备忘】Android ndk下用AssetManager读取assets的资源。 @import url(http://www.cppblog.com/cutesoft_client/cuteed...

【JNI】bug assets 文件 AAssetManager_open 无法打开

第一次使用jni 的AAssetManager_open 函数打开 assets文件失败,网上查也没发现线索,导入NativeAudio 例程,访问是可以的,之后查3小时才发现一个简单的原因-- --...

Android apk安装过程及Java、JNI读取安装包内assets资源文件的两种方法(附源码实例)

问题背景:在PC上的程序可以轻松使用./或不用指明,默认读取的就是程序所在路径内的文件。但在Android上,应用程序被打包成apk,程序运行时无法直接获取apk(压缩包)内的文件。但在一些特殊场合,...

android常见问题之jni读取assets资源文件(附源码)

assets目录底下的文件会被打包到一个apk文件里,这些资源在安装时他们并没被解压,使用时是直接从apk中读取的。这里介绍下怎么在jni内使用ndk自带api的接口函数读取assets资源文件,和l...
  • fontlose
  • fontlose
  • 2011年08月14日 16:11
  • 18168

Android Ndk: 如何从native层直接获取 assets文件夹下的文件

这篇博文写的特别好 http://androgeek.info/?p=275 从Native层 直接读取 Android 工程目录 下 Asserts目录下的文件 具体思路如下: Androi...

android JNI层读取assets目录文件

最近在做app加固方面的技术,遇到了一个问题,就是需要把assets目录下加密的文件写到目标app的/data/data/目录,研究了一下发现是可以实现的,下面直接上关键代码: (注:1:用的时候一定...

android开发--- jni读取assets资源文件

在ndk的demo程序hello-jni修改 在assets目录中添加文件log.txt,里面随便写点什么,hello,world好了   在ndk...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

fatal error: android/asset_manager.h: No such file or directory

在mac 终端上执行3.1.1 的build_native.py 报错 fatal error: android/asset_manager.h: No such file or directory ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android常见问题之jni读取assets资源文件
举报原因:
原因补充:

(最多只允许输入30个字)