JNI读取assets资源文件
源自:http://www.rosoo.net/a/201112/15459.html
assets目录底下的文件会被打包到一个apk文件里,这些资源在安装时他们并没被解压,使用时是直接从apk中读取的。这里介绍下怎么在jni内使用 ndk自带api的接口函数读取assets资源文件,和libzip库函数的使用,可以用来读创建修改压缩文档,这里也是以读取apk安装包内的资源
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 : 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的移植可以参考老外做的android-ndk-assets.zip这个工程,已在NDK下可以编译了,修改下编译生成libzip.so,利用libzip.so和zip.h建立工程,使用libzip还可以读取apk包内其他压缩文件如AndroidManifest.xml布局xml等。
- /*************************************
- * Function Name : java_com_fontlose_ReadAssets_readFromAssetsLibzip
- * Description : 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<numFiles; i++) {
- const char* name = zip_get_name(apkArchive, i, 0);
- if (name == NULL) {
- LOGE("Error reading zip file name at index %i : %s", zip_strerror(apkArchive));
- return;
- }
- zip_stat(apkArchive,name,0,&fstat);
- LOGI("File %i:%s Size1: %d Size2: %d", i,fstat.name,fstat.size ,fstat.comp_size) ;
- }
- const char *fname = (*env)->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)
JNI读取assets资源文件的更多相关文章
- QLGame 2d Engine Android端环境搭建(通过jni读取assets目录的文件)
QLGame 2d Engine win端已经实现了一个动物的动画了,初步的东西已经完成,考虑在Android端也实现这些基本的东西,这样跨平台的引擎也就实现了! 要在Android下编程,首先要实现 ...
- Android学习--Assets资源文件读取及AssetManager介绍
APK安装过程 复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用 ...
- Hadoop集群上使用JNI,调用资源文件
hadoop是基于java的数据计算平台,引入第三方库,例如C语言实现的开发包将会大大增强数据分析的效率和能力. 通常在是用一些工具的时候都要用到一些配置文件.资源文件等.接下来,借一个例子来说明ha ...
- SpringBoot读取静态资源文件
ClassPathResource resource = new ClassPathResource(publicKeyCer); File file = null; try { file = res ...
- Spring读取properties资源文件
我们知道可以通过读取资源文件流后加载到Properties对象,再使用该对象方法来获取资源文件.现在介绍下利用Spring内置对象来读取资源文件. 系统启动时加载资源文件链路:web.xml --&g ...
- SpringBoot打成jar包后无法读取resources资源文件
在项目中做了一个支付功能, 需要引入第三方渠道的配置文件config.xml用来初始化文件证书, 将配置文件 config.xml 放到 resources 资源目录下. 本地开发环境下能正常读取该文 ...
- 在服务端中,读取properties资源文件中的数据
1.获取到资源的路径 2.读取数据 //properties文件对象 Properties properties = new Properties(); //通过HttpServletRequest ...
- Java项目读取resources资源文件路径那点事
今天在Java程序中读取resources资源下的文件,由于对Java结构了解不透彻,遇到很多坑.正常在Java工程中读取某路径下的文件时,可以采用绝对路径和相对路径,绝对路径没什么好说的,相对路径, ...
- win10 uwp 读取resw资源文件
ResourceContext resourceContext = ResourceContext.GetForViewIndependentUse(); ResourceMap resourceMa ...
随机推荐
- 【转载】MySQL 日志 undo | redo
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- Android学习笔记:TabHost 和 FragmentTabHost(转)
转自:http://www.cnblogs.com/asion/p/3339313.html 作者:Asion Tang 出处:http://asiontang.cnblogs.com T ...
- python学习小结3:函数
Python是对接口编程,而不是对数据类型编程.例如我们定义了一个函数,在函数里用到了in这个接口,那么只要传入的参数实现了这个接口就可以,我们不在乎它是list还是tuple. 简单的函数 使用de ...
- 深入浅出百度地图API开发系列(1):前言
百度地图API目前在地图API领域越来越受到众多开发者的关注,许多应用都使用到了百度地图API服务,包括博主me,我自己使用做的是Javascript API,根据经验,我想整理出一份系列教程,如果能 ...
- c++ 函数返回指针 及用法
#include<string> #include<iostream> using namespace std; string fun1(int a) { string str ...
- 用windows远程连接linux桌面(使用tightvnc或者tigervnc)
一.安装tightvnc: tightvnc的安装在安装包中有详细的说明(README文件) 首先你要确保linux已经安装jpeg和zlib库, 2.编译 执行如下两个命令: [root@local ...
- java内存分配详细论
P.S. 想写这篇总结酝酿了有个来月了,却始终感觉还差点什么东西,一直未敢动笔. 最近两天连夜奋战,重新整理下前面查阅的资料.笔记,还是决定将它写出来. 现在提出几个问题,如果都能熟练回答的大虾,请您 ...
- 时序列数据库武斗大会之TSDB名录 Part 2
[编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...
- poj 3083 Children of the Candy Corn (广搜,模拟,简单)
题目 靠墙走用 模拟,我写的是靠左走,因为靠右走相当于 靠左走从终点走到起点. 最短路径 用bfs. #define _CRT_SECURE_NO_WARNINGS #include<stdio ...
- java基础知识回顾之---java String final类普通方法的应用之“子串在整串中出现的次数”
/* * 2 一个子串在整串中出现的次数. * "loveerlovetyloveuiloveoplove" * 思路: * 1,要找的子串是否存在,如果存在获取其出现的位置.这个 ...