在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文件的更多相关文章

  1. Android应用安全之外部动态加载DEX文件风险

    1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...

  2. [转载] Android动态加载Dex机制解析

    本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422 1.什么是类加载器? 类加载器(class loader)是 Java ...

  3. Android 动态加载 (二) 态加载机制 案例二

    探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...

  4. Android 动态加载 (一) 态加载机制 案例一

    在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...

  5. Android动态加载技术初探

    一.前言: 现在,已经有实力强大的公司用这个技术开发应用了,比如淘宝,大众点评,百度地图等,之所以采用这个技术,实际上,就是方便更新功能,当然,前提是新旧功能的接口一致,不然会报Not Found等错 ...

  6. Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类

    前言 近期做换肤功能,由于换肤程度较高,受限于平台本身,实现起来较复杂,暂时搁置了该功能,但也积累了一些经验,将分两篇文章来写这部分的内容,欢迎交流! 关键字:Android动态加载 声明 欢迎转载, ...

  7. Android动态加载jar/dex

    前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优 ...

  8. 【Android】Android动态加载Jar、APK的实现

    本文介绍Android中动态加载Jar.APK的实现.而主要用到的就是DexClassLoader这个类.大家都知道Android和普通的Java虚拟机有差别,它只能加载经过处理的dex文件.而加载这 ...

  9. Android动态加载ListView中的Item

    我这周上网看到动态增加listview的每一项item的布局,今天抽空自己写了一个,方便自己日后使用,这个效果还是很不错的,用到了Adapter的notifyDataSetChanged()方法,当点 ...

随机推荐

  1. Codeforces 55D Beautiful Number

    Codeforces 55D Beautiful Number a positive integer number is beautiful if and only if it is divisibl ...

  2. 【算法】桶排->冒泡->快排

    啊哈 算法 http://pan.baidu.com/s/1jGGl2SI http://pan.baidu.com/s/15C1oq 1 节 最快最简单的排序——桶排序 在我们生活的这个世界中到处都 ...

  3. Win10 IIS以及ASP.NET 4.0配置问题日志

    问题日志 升级到Win10并安装了VS2015后,原有ASP.NET 4.0项目在本机的IIS部署出现问题. 安装IIS: 在[控制面板.程序.启用或关闭Windows功能.Internet Info ...

  4. 开发设计模式(九)门面模式(Facade Pattern)

    什么是门面模式? 门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行.门面模式提供一个高层次的接口,使得子系统更易于使用. 大家都写过纸质的信件吧,比如给女朋友写 ...

  5. JQ实现3D拖拽效果

    <!DOCTYPE HTML> <html onselectstart='return false'> <head> <meta http-equiv=&qu ...

  6. HTML5下通过response header解决跨域AJAX cookie的问题

    ajax: 通过给Response Header添加Access-Control-Allow-Origin:*  来解决跨域请求,*代表允许所有的跨域请求,或者把*换成指定的域名 cookie: 服务 ...

  7. 判断数据库表字段是否为null值,采用is null

    use UserCentergo select * from AccountDetails1.判断一个字段是否为null值,进行查询:update AccountDetails set Project ...

  8. POJ 3349 Snowflake Snow Snowflakes(哈希)

    http://poj.org/problem?id=3349 题意 :分别给你n片雪花的六个角的长度,让你比较一下这n个雪花有没有相同的. 思路:一开始以为把每一个雪花的六个角的长度sort一下,然后 ...

  9. 服务器部署_nginx报错: [warn] conflicting server name "www.test.com" on 0.0.0.0:80, ignored

    今天修改nginx配置文件nginx.conf之后,启动nginx就会报错.经仔细检查是重复配置了 server元素导致, 当nginx检测到重复的 server_name item.test.com ...

  10. 用Unity3.0+MVC4搭建项目

    新年快乐!又是新的一年到来了,我好久没有在园子里面做笔记啦,由于工作上的事,还好年前把该做的都完善了,于是就写了辞职信.由于家庭原因,不得不离职,在春节期间呢,我放松了几天,去这里去那里的,朋友们喜欢 ...