Android动态加载so文件
在Android中调用动态库文件(*.so)都是通过jni的方式,而且往往在apk或jar包中调用so文件时,都要将对应so文件打包进apk或jar包,工程目录下图:

以上方式的存在的问题:
1、缺少灵活性比较类似静态加载了(不是静态加载),能加载的so文件绑定死了;
2、但so文件很多或很大时,会导致对应的apk和jar包很大;
3、不能动态的对so文件更新;
Android中加载so文件的提供的API:
void System.load(String pathName);
说明:
1、pathName:文件名+文件路劲;
2、该方法调用成功后so文件中的导出函数都将插入的系统提供的一个映射表(类型Map);
看到以上对System.load(String pathName);的函数说明可定有人会想到将so文件放到一个指定的目录然后再通过参数pathName直接引用该目录的路劲和对应的so文件问题不就解决了吗?
这里有个问题被忽略了,那就是System.load只能加载两个目录路劲下的so文件:
1、/system/lib ;
2、安装包的路劲,即:/data/data/<packagename>/…
而且这两个路劲又是有权限保护的不能直接访问;
问题解决方法:
先从网络下载so文件到手机目录(如:/test/device/test.so) –> 将test.so加载到内存(ByteArrayOutputStream) –> 然后保存到对用安装包目录;
具体代码如下:
try {
String localPath = Environment.getExternalStorageDirectory() + path;
Log.v(TAG, "LazyBandingLib localPath:" + localPath);
String[] tokens = mPatterns.split(path);
if (null == tokens || tokens.length <= 0
|| tokens[tokens.length - 1] == "") {
Log.v(TAG, "非法的文件路径!");
return -3;
}
// 开辟一个输入流
File inFile = new File(localPath);
// 判断需加载的文件是否存在
if (!inFile.exists()) {
// 下载远程驱动文件
Log.v(TAG, inFile.getAbsolutePath() + " is not fond!");
return 1;
}
FileInputStream fis = new FileInputStream(inFile);
File dir = context.getDir("libs", Context.MODE_PRIVATE);
// 获取驱动文件输出流
File soFile = new File(dir, tokens[tokens.length - 1]);
if (!soFile.exists()) {
Log.v(TAG, "### " + soFile.getAbsolutePath() + " is not exists");
FileOutputStream fos = new FileOutputStream(soFile);
Log.v(TAG, "FileOutputStream:" + fos.toString() + ",tokens:"
+ tokens[tokens.length - 1]);
// 字节数组输出流,写入到内存中(ram)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
// 从内存到写入到具体文件
fos.write(baos.toByteArray());
// 关闭文件流
baos.close();
fos.close();
}
fis.close();
Log.v(TAG, "### System.load start");
// 加载外设驱动
System.load(soFile.getAbsolutePath());
Log.v(TAG, "### System.load End");
return 0;
} catch (Exception e) {
Log.v(TAG, "Exception " + e.getMessage());
e.printStackTrace();
return -1;
}
Android动态加载so文件的更多相关文章
- Android应用安全之外部动态加载DEX文件风险
1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...
- [转载] Android动态加载Dex机制解析
本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422 1.什么是类加载器? 类加载器(class loader)是 Java ...
- Android 动态加载 (二) 态加载机制 案例二
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...
- Android 动态加载 (一) 态加载机制 案例一
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- Android动态加载技术初探
一.前言: 现在,已经有实力强大的公司用这个技术开发应用了,比如淘宝,大众点评,百度地图等,之所以采用这个技术,实际上,就是方便更新功能,当然,前提是新旧功能的接口一致,不然会报Not Found等错 ...
- Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类
前言 近期做换肤功能,由于换肤程度较高,受限于平台本身,实现起来较复杂,暂时搁置了该功能,但也积累了一些经验,将分两篇文章来写这部分的内容,欢迎交流! 关键字:Android动态加载 声明 欢迎转载, ...
- Android动态加载jar/dex
前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优 ...
- 【Android】Android动态加载Jar、APK的实现
本文介绍Android中动态加载Jar.APK的实现.而主要用到的就是DexClassLoader这个类.大家都知道Android和普通的Java虚拟机有差别,它只能加载经过处理的dex文件.而加载这 ...
- Android动态加载ListView中的Item
我这周上网看到动态增加listview的每一项item的布局,今天抽空自己写了一个,方便自己日后使用,这个效果还是很不错的,用到了Adapter的notifyDataSetChanged()方法,当点 ...
随机推荐
- python基础学习(二)--函数
return返回值: python函数都有返回值,函数体内无return,默认返回值None, 函数参数: 1.普通参数 严格按照顺序,将实际参数赋值给形式参数,一一对应. 例: def send(x ...
- easy-ui datagrid
Easy-ui引用 <link href="css/EasyUI/themes/icon.css" rel="stylesheet" type=&q ...
- JLOI 2013 卡牌游戏
问题描述: N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先 ...
- python机器学习库
http://scikit-learn.org/stable/install.html
- ZOJ 3603 Draw Something Cheat
点我看题目 题意 : 给你n个字符串,让你找出在每个字符串中出现的字母,按字典序输出来. 思路 :一开始想差了,以为记录下每个字符出现次数,然后找次数大于1的,可是我忘了可能在一个字符串中有AA,而另 ...
- HDU1395+快速幂
#include<stdio.h> int fast_pow( int a,int b,int mod ){ ; ){ == ){ res = res*a%mod; } a = a*a%m ...
- PHP file_exists() 函数
定义和用法 file_exists() 函数检查文件或目录是否存在. 如果指定的文件或目录存在则返回 true,否则返回 false. 语法 file_exists(path) 参数 描述 path ...
- QT中的字符串处理函数
Fn 1 : arg 这个函数的具体声明不写了,它有20个重载,典型的示例代码如下: 1: #include <QtCore/QCoreApplication> 2: #include & ...
- Android include的使用
如果在程序中多次用到一部分相同的布局,可以先将这部分布局定义为一个单独的XML,然后在需要的地方通过<include>引入,如下: main.xml <?xml version=&q ...
- Django中的Model继承
Django 中的 model 继承和 Python 中的类继承非常相似,只不过你要选择具体的实现方式:让父 model 拥有独立的数据库:还是让父 model 只包含基本的公共信息,而这些信息只能由 ...