在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) �C> 将test.so加载到内存(ByteArrayOutputStream) �C> 然后保存到对用安装包目录;

具体代码如下:

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;

}


更多相关文章

  1. Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实
  2. Android(安卓)11 中的隐私权更新 :存储机制更新
  3. 在Android中通过jni方式使用编译好的FFmpeg库-Android中使用FFmp
  4. android基于dialog加载时转圈圈的demo
  5. Android下使用JDOM访问XML文件
  6. Android(安卓)引用外部项目库
  7. 一次偶然机遇找到一个不错的关于Android实现加载gif动画的实例,写
  8. [Android(安卓)之美] 那些你不知道的APK 瘦身,让你的APK更小
  9. android/NDK开发assets资源中文名打包问题

随机推荐

  1. Android(安卓)创建其它应该程序的上下文
  2. Android教程收集贴
  3. android取得账户(邮件地址)
  4. Android 获取闹钟引发的血案
  5. android 调用java编写接口 简单示例
  6. Android测试,Android(安卓)Studio中的单元
  7. android Webview基本配置以及android与js
  8. Android时间选择器对话框的使用
  9. Android 设置TextView滑动滚动条和滑动效
  10. ANDROID – 使用特定的URL开启应用程序