博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)android常见问题之jni读取assets资源文件(附源码)
阅读量:4459 次
发布时间:2019-06-08

本文共 6046 字,大约阅读时间需要 20 分钟。

(转)

  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。

/******************************************************************************** Function Name  : java_com_fontlose_ReadAssets_readFromAssets* Description    : 定义:public native void  readFromAssets(AssetManager ass,String filename);* Input          : AssetManager对象 filename资源名* Output         : None* Return         : None*******************************************************************************/ void  Java_com_fontlose_ReadAssets_readFromAssets(JNIEnv* env,jclass tis,jobject assetManager,jstring filename){   LOGI("ReadAssets");    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);   if(mgr==NULL)   {      LOGI(" %s","AAssetManager==NULL");      return ;   }     /*获取文件名并打开*/   jboolean iscopy;   const char *mfile = (*env)->GetStringUTFChars(env, filename, &iscopy);   AAsset* asset = AAssetManager_open(mgr, mfile,AASSET_MODE_UNKNOWN);   (*env)->ReleaseStringUTFChars(env, filename, mfile);   if(asset==NULL)   {      LOGI(" %s","asset==NULL");      return ;   }   /*获取文件大小*/   off_t bufferSize = AAsset_getLength(asset);   LOGI("file size         : %d\n",bufferSize);   char *buffer=(char *)malloc(bufferSize+1);   buffer[bufferSize]=0;   int numBytesRead = AAsset_read(asset, buffer, bufferSize);   LOGI(": %s",buffer);   free(buffer);    /*关闭文件*/   AAsset_close(asset);}

 

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

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的移植可以参考老外做的这个工程,已在NDK下可以编译了,修改下编译生成libzip.so,利用libzip.so和zip.h建立工程,使用libzip还可以读取apk包内其他压缩文件如AndroidManifest.xml布局xml等。

/******************************************************************************** Function Name  : java_com_fontlose_ReadAssets_readFromAssetsLibzip* Description    : 定义:public native void  readFromAssetsLibzip(String apkpath,String filename);* Input          : apkpath路径 filename 资源名* Output         : None* Return         : None*******************************************************************************/ void  Java_com_fontlose_ReadAssets_readFromAssetsLibzip(JNIEnv* env,jclass tis,jstring assetpath,jstring filename){   LOGI("ReadAssets");   int i=0;   jboolean iscopy;   const char *mpath = (*env)->GetStringUTFChars(env, assetpath, &iscopy);   struct zip* apkArchive=zip_open(mpath, 0, NULL);;   (*env)->ReleaseStringUTFChars(env, filename, mpath);   struct zip_stat fstat;   zip_stat_init(&fstat);   int numFiles = zip_get_num_files(apkArchive);   LOGI("File numFiles %i \n",numFiles);   for (i=0; i
GetStringUTFChars(env, filename, &iscopy); struct zip_file* file = zip_fopen(apkArchive, fname, 0); if (!file) { LOGE("Error opening %s from APK", fname); return; } zip_stat(apkArchive,fname,0,&fstat); (*env)->ReleaseStringUTFChars(env, filename, fname); char *buffer=(char *)malloc(fstat.size+1); buffer[fstat.size]=0; int numBytesRead = zip_fread(file, buffer,fstat.size);; LOGI(": %s\n",buffer); free(buffer); zip_fclose(file); zip_close(apkArchive);}

 

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

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如下

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

log.txt内容如下

。。。。。。。。。。。。。。。。  这个例子从jni读取assets内文件  。。。。。。。。。。。。。。。。

jni工程和测试工程源码我已上传到我的资源 有兴趣的童鞋可以下来看下

转载于:https://www.cnblogs.com/keis/archive/2011/11/06/2238147.html

你可能感兴趣的文章
PHP实用代码片段(二)
查看>>
按时间分区自动建分区表
查看>>
centos7安装golang
查看>>
Go VUE --- vuejs在服务器部署?
查看>>
各种排序算法原理图
查看>>
ASP.NET Core Middleware管道介绍
查看>>
SQL 外键
查看>>
二叉树的三种非递归遍历和层次遍历
查看>>
centos7 update network time
查看>>
装饰模式
查看>>
苹果新的编程语言 Swift 语言进阶(十一)--实例的初始化与类的析构
查看>>
node.js整理 03文件操作-遍历目录和文本编码
查看>>
mysql字段累加concat
查看>>
TCP协议的三次握手和四次挥手过程
查看>>
linux内核中有哪些子系统(框架)呢?
查看>>
python built-in zip()
查看>>
Android AsynTask更新主界面
查看>>
yii使用CUploadedFile上传文件
查看>>
《redis-php中文参考手册》
查看>>
System.IO.File.Create 不会自动释放,一定要Dispose
查看>>