昨天突然之间看到linux加载so,然后同事突然问我android怎么加载的,然后我但是也懵逼了,so库不是在本地加载的吗?然后他说不是,然后就去查了下,我们平时用的都是在main/jniLibs下的*.so文件。于是就找了下,有大神些过。然而我当时也不懂,看了就记录下来。
支持原创:http://mp.weixin.qq.com/s/MjVnODQkk5rBFxHt4jA4NQ

在android中加载so有两种方式。

静态加载

其实静态方式就是将so包和apk或者jar的方式打包在一起,这样就导致了不灵活,apk包可能比较大。

动态加载

动态加载的优点

1、灵活,so库可以动态的更新。
2、so如果比较大的话可以减少apk的大小
3、解决了多个第三方的so库文件同时加载造成的冲突。

注意事项:

android提供给了api:

//第一种。pathName库文件的绝对路径viod Sytem.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加载

1、下载so

这个应该都懂,用okhttp下载,假设下载的路径是/mnt/sdcard/armeabi 目录

2、复制目录到包路径下

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

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 < currentFiles.length; i++) {            if (currentFiles[i].getName().contains("libwedsa23")) {                hasSoLib = true;            }        }        return hasSoLib;    }    /**     *     * @param fromFile 指定的下载目录     * @param toFile 应用的包路径     * @return     */    public static int copy(String fromFile, String toFile) {        //要复制的文件目录        File[] currentFiles;        File root = new File(fromFile);        //如同判断SD卡是否存在或者文件是否存在,如果不存在则 return出去        if (!root.exists()) {            return -1;        }        //如果存在则获取当前目录下的全部文件 填充数组        currentFiles = root.listFiles();        //目标目录        File targetDir = new File(toFile);        //创建目录        if (!targetDir.exists()) {            targetDir.mkdirs();        }        //遍历要复制该目录下的全部文件        for (int i = 0; i < currentFiles.length; i++) {            if (currentFiles[i].isDirectory()) {                //如果当前项为子目录 进行递归                copy(currentFiles[i].getPath() + "/", toFile + currentFiles[i].getName() + "/");            } else {                //如果当前项为文件则进行文件拷贝                if (currentFiles[i].getName().contains(".so")) {                    int id = copySdcardFile(currentFiles[i].getPath(), toFile + File.separator + currentFiles[i].getName());                }            }        }        return 0;    }    //文件拷贝    //要复制的目录下的所有非子目录(文件夹)文件拷贝    public static int copySdcardFile(String fromFile, String toFile) {        try {            FileInputStream fosfrom = new FileInputStream(fromFile);            FileOutputStream fosto = new FileOutputStream(toFile);            ByteArrayOutputStream baos = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int len = -1;            while ((len = fosfrom.read(buffer)) != -1) {                baos.write(buffer, 0, len);            }            // 从内存到写入到具体文件            fosto.write(baos.toByteArray());            // 关闭文件流            baos.close();            fosto.close();            fosfrom.close();            return 0;        } catch (Exception ex) {            return -1;        }    }}
3、gradle指定cpu架构
defaultConfig {        ndk {            abiFilters "armeabi","armeabi-v7a","x86"        }    }
4、load加载so文
File dir =  getApplicationContext().getDir("l  ibs", Context.MODE_PRIVATE);File[] currentFiles;currentFiles = dir.listFiles();for (int i = 0; i < currentFiles.length; i++) {   System.load(currentFiles[i].getAbsolutePath());}

ok~就这样实现了动态的加载so库。

更多相关文章

  1. ndk编译android上运行的c程序
  2. android studio中出现的问题
  3. RSS阅读器(使用android解析技术解析xml文件并以列表的形式显示出
  4. Android(安卓)源码本地编译脚本 & 编译Android系统
  5. android 热更新(无框架)
  6. 浅入浅出 Android(安卓)安全:第六章 Android(安卓)安全的其它话题
  7. Mac OS X下用Eclipse浏览和编译Android源代码
  8. Android工程目录介绍
  9. Android是怎样调用硬件加速的

随机推荐

  1. Gesture Detector
  2. Android开发入门之学习笔记(四):程序窗口的
  3. Android System Server大纲之VibratorSer
  4. 使用TextView/EditText应该注意的地方
  5. Android(安卓)6.0 HTTPS SSL 无法访问,提
  6. 实现Android ListView 自动加载更多内容
  7. Android Studio 报Integer types not all
  8. 【安卓】Android播放器的三种实现方法
  9. WebView Android 调用js且须要获取返回结
  10. Android系统手机端抓包方法