首页 存档 技术 查看内容

Android 开发中如何动态加载 so 库文件

2018-3-30 13:00 |来自: 互联网 1184 0

摘要: 【回复“1024”,送你一个特别推送】 我想对于静态加载 so 库文件,大家都已经很熟悉了,这里就不多说了。在 Android 开发中调用动态库文件(*.so)都是通过 jni 的方式,而静态加载往往是在 apk 或 jar 包中调用so文 ...

【回复“1024”,送你一个特别推送】

我想对于静态加载 so 库文件,大家都已经很熟悉了,这里就不多说了。在 Android 开发中调用动态库文件(*.so)都是通过 jni 的方式,而静态加载往往是在 apk 或 jar 包中调用so文件时,都要将对应 so 文件打包进 apk 或 jar 包。

动态加载的优点

静态加载,不灵活,apk 包有可能大。所以采用动态加载 so 库文件,有以下几点好处:

  1. 灵活,so 文件可以动态加载,不是绑定死的,修改方便,so 库有问题,我们可以动态更新。

  2. so 库文件很大的话,采用动态加载可以减少 apk 的包,变小。

  3. 其实我们常用第三方 so 库,单个可能没问题,如果多个第三方 so 库文件,同时加载可能会出现冲突,而动态加载就能够解决这一问题。

注意路径陷阱

动态加载 so 库文件,并不是说可以把文件随便存放到某个 sdcard 文件目录下,这样做既不安全,系统也加载不了。

我们在 Android 中加载 so 文件,提供的 API 如下:

//第一种,pathName 库文件的绝对路径
void System.load(String pathName);
//第二种,参数为库文件名,不包含库文件的扩展名,必须是在JVM属性Java.library.path所指向的路径中,路径可以通过System.getProperty('java.library.path') 获得
void loadLibrary(String libname)

注意:而这里加载的文件路径只能加载两个目录下的 so 文件。那就是:

  1. /system/lib

  2. 应用程序安装包的路径,即:/data/data/packagename/…

所以,so 文件动态加载的文件目录不能随便放。这是需要注意的一点。

实现思路

既然使用动态加载的好处和陷阱我们都大致了解了,那就可以在实现的时候,注意陷阱就可以了。那基本思路如下:

  1. 网络下载 so 文件到指定目录

  2. 从指定下载的目录复制 copy so文件到可动态加载的文件目录下,比如:/data/data/packagename/…

  3. 配置 gradle ,指定 cpu 架构

  4. load 加载

第一步,我们这里可以简单忽略,假设我们把 so 文件下载到了 /mnt/sdcard/armeabi 目录下。

复制目录到包路径下

那我们就应该把 /mnt/sdcard/armeabi 目录下的 so 文件,复制到 应用的包路径下。

/**
 * Created by loonggg on 2017/3/29.
 */
public class SoFile { /** * 加载 so 文件 * @param context * @param fromPath 下载到得sdcard目录 */ public static void loadSoFile(Context context, String fromPath) { File dir = context.getDir("libs", Context.MODE_PRIVATE); if (!isLoadSoFile(dir)) { copy(fromPath, dir.getAbsolutePath()); } } /** * 判断 so 文件是否存在 * @param dir * @return */ public static boolean isLoadSoFile(File dir) { File[] currentFiles; currentFiles = dir.listFiles(); boolean hasSoLib = false; if (currentFiles == null) { return false; } for (int i = 0; i
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部