在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. [转载]C#读取Excel几种方法的体会

    C#读取Excel几种方法的体会 转载地址:http://developer.51cto.com/art/201302/380622.htm (1) OleDb: 用这种方法读取Excel速度还是非常 ...

  2. 软件测试 -- 测试人员和QA的区别

    软件测试人员的职责是尽可能早的找出软件缺陷,确保得以修复. 而质量保证人员(QA)主要职责是创建或者制定标准和方法,提高促进软件开发能力和减少软件缺陷. 测试人员的主要工作是测试,质量保证人员日常工作 ...

  3. Unity3d Shader开发(三)Pass(Blending )

    混合被用于制作透明物体. 当图像被渲染时,所有着色器被执行以后,所有贴图被应用后,像素将被写到屏幕.他们是如何通过Blend命令的控制和已有的图像合并呢? Syntax 语法 Blend Off Tu ...

  4. 关于博客名“大话济公”的说明

    其实本来没打算起这个名字的,换了几个名字都被占用了(无语啊...).最近呢,我在研究<济公传>,对于济公的传说比较喜欢,尤其是这个任务,诙谐幽默,同时有时时刻刻在帮助有困难的群众,虽然是个 ...

  5. DOS系统里,分屏显示目录的命令是什么??

    dir /sdir /pdir /w 我记得这三个都是我当年常用的命令,有分瓶的,有滚动时候每页停顿的,还有去掉详细信息的吧,, 可以放在一起使用.如dir /p/w /p是滚动时候中间停顿的,/w是 ...

  6. 深入研究java.lang.ProcessBuilder类

     深入研究java.lang.ProcessBuilder类 一.概述       ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它 ...

  7. C# 发送邮件实例代码

    1.构造附件 static List<Attachment> BuildAttachments(List<EmailFile> files) { ) { return null ...

  8. 一位IT行业高收入者的理财规划方案

    一位IT行业高收入者的理财规划方案 http://zhuanlan.zhihu.com/invest/19670220 Alex · 12 天前 回望2013,这一年是极其不寻常的.理财浪潮席卷大江南 ...

  9. 在eclipse中将项目发布到tomcat的root目录

    (1)设置项目上下文,右击项目-properties   >Web Page Edit

  10. 乱想-What&Why

    今天去海淀书城看书,目的很明确,本来是想买<WCF技术剖析>的下册(2010年3月份买了上册,当时下册没出来),谁知这本书不单卖,要和上册一起卖,扫兴. 兴致减半,索性找了旁边的基本Jav ...