一、背景

在开发Android应用程序的实现,有时候需要引入第三方so lib库,但第三方so库比较大,例如开源第三方播放组件ffmpeg库, 如果直接打包的apk包里面, 整个应用程序会大很多.经过查阅资料和实验,发现通过远程下载so文件,然后再动态注册so文件时可行的。主要需要解决下载so文件存放位置以及文件读写权限问题。

二、主要思路

 

1、首先把so放到网络上面,比如测试放到:http://codestudy.sinaapp.com/lib/test.so

2、应用启动时,启动异步线程下载so文件,并写入到/data/data/packageName/app_libs目录下面

3、调用System.load 注册so文件。因路径必须有执行权限,我们不能加载SD卡上的so,但可以通过调用context.getDir("libs", Context.MODE_PRIVATE)把so文件写入到应用程序的私有目录/data/data/packageName/app_libs。

三、代码实现

 

1、网络下载so文件,并写入到应用程序的私有目录/data/data/PackageName/app_libs

/**
* 下载文件到/data/data/PackageName/app_libs下面
* @param context
* @param url
* @param fileName
* @return
*/
public static File downloadHttpFileToLib(Context context, String url, String fileName) {
long start = System.currentTimeMillis();
FileOutputStream outStream = null;
InputStream is = null;
File soFile = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
File dir = context.getDir("libs", Context.MODE_PRIVATE);
soFile = new File(dir, fileName);
outStream = new FileOutputStream(soFile);
is = entity.getContent();
if (is != null) {
byte[] buf = new byte[1024];
int ch = -1;
while ((ch = is.read(buf)) > 0) {
outStream.write(buf, 0, ch);
//Log.d(">>>httpDownloadFile:", "download 进行中....");
}
}
outStream.flush();
long end = System.currentTimeMillis();
Log.d(">>>httpDownloadFile cost time:", (end-start)/1000 + "s");
Log.d(">>>httpDownloadFile:", "download success");
return soFile;
} catch (IOException e) {
Log.d(">>>httpDownloadFile:", "download failed" + e.toString());
return null;
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

 2、调用System.load 注册so文件

new Thread(new Runnable() {
@Override
public void run() {
File soFile = FileUtils.downloadHttpFileToLib(getApplicationContext(), "http://codestudy.sinaapp.com//lib/test.so", "test.so");
if (soFile != null) {
try {
Log.d(">>>loadAppFile load path:", soFile.getAbsolutePath());
System.load(soFile.getAbsolutePath());
} catch (Exception e) {
Log.e(">>>loadAppFile load error:", "so load failed:" + e.toString());
}
}
}
}).start();

  

四、需要解决的问题

1、so文件下载以及注册时机。测试发现libffmpeg.so  8M的文件单线程下载需要10-13s左右

2、so下载失败或者注册失败该怎么处理。例如so播放组件是否尝试采用android系统原生MediaPlayer进行播放

3、当初次so还没有下载完注册成功时,进入播放页面时,需要友好提示用户,比如loading 视频正在加载等等

4、无网络情况等等情况

 

五、说明

 

 上面的demo经过3(2.3/4.2/4.4)实际机型测试可以正常使用,然后根据第四点列举问题完善以下,即可使用。

Android so lib库远程http下载和动态注册的更多相关文章

  1. android多lib库工程的自动批量构建--准备

    打包这个活儿吧,本来没什么技术含量,千篇一律的更改渠道名称,然后编译,签名即可.但是如果发布渠道比较多的话,这种重复工作让人烦不胜烦.我们的应用发布渠道有30多个,若是手工打包,基本不用做其他的事情了 ...

  2. android多lib库工程的自动批量构建--编写ant脚本

    基本配置--build.properties 首先编写基本配置build.properties ,主要配置如下: android sdk所在目录 编译项目所使用的项目版本 Jdk所在目录 以及签名时, ...

  3. Android 动态注册JNI函数

    1.JNI函数注册方式 在Android开发中,由于种种原因我们需要调用C/C++代码,在这个时候我们就需要使用jni了, jni在使用时要对定义的函数进行注册,这样java才能通过native关键字 ...

  4. Android只能动态注册的广播Action

    只能动态注册的广播(部分): android.intent.action.SCREEN_ON android.intent.action.SCREEN_OFF android.intent.actio ...

  5. 解决android studio引用远程仓库下载慢(转)

    解决android studio引用远程仓库下载慢(JCenter下载慢) 第一种方法 使用开源中国的maven库 阿里云的(速度飞快):http://maven.aliyun.com/nexus/c ...

  6. 如何把一个android工程作为另外一个android工程的lib库

    http://zhidao.baidu.com/question/626166873330652844 一个工程包含另一个工程.相当于一个jar包的引用.但又不是jar包反而像个package 在网上 ...

  7. android studio 引用远程仓库下载慢(JCenter下载慢)的办法

    https://blog.csdn.net/linglingchenchen/article/details/62236723 解决android studio引用远程仓库下载慢(JCenter下载慢 ...

  8. android 如何添加第3方lib库到kernel中

    注意:只能将lib库放在kernel编译到的地方,如下: alps/kernel/ alps/mediatek/custom/common/kernel/ alps/mediatek/custom/$ ...

  9. Android Studio提交库至Bintray jCenter从入门到放弃

    文:http://blog.csdn.net/sk719887916/article/details/52473914 作者:Tamic 详细文章请看:[Gradle系列]Gradle发布module ...

随机推荐

  1. Bootstrap 表格和按钮

    一.表格 1.条纹状表格 行产生一行隔一行加单色背景效果 注:表格效果需要基于基本格式.table <table class="table table-striped"> ...

  2. 低功耗蓝牙4.0BLE编程-nrf51822开发(3)

    蓝牙协议栈 nrf51822开发中,蓝牙协议栈和应用开发是分开的. (1)兼容蓝牙4.0低功耗协议栈基带层,L2CAP\AAT\SM\GAP\GATT协议,设备和广播,GATT客户端和服务器,SMP支 ...

  3. python 十进制 十六进制

    把十六进制的字串转为十进制数字:>>> print int('ff', 16)   255 把十进制数字转换为以十六进制表示之字串,可调用内置的hex()函数:>>> ...

  4. Visual Studio 2005安装qt-win-commercial-src-4.3.1,并设置环境变量

    虽然已经在Visual Studio 2005下安装Qt4已经n次了,还是打算在上写写安装方法. qt-win-commercial-src-4.3.1.zip.qt-vs-integration-1 ...

  5. HAL层Camera模块Dump图片--工作积累

    Camera的raw data一般都是YUV420的格式,数据的特点是: YUV 4:2:0采样,每四个Y共用一组UV分量 YUV420格式: 先Y,后V,中间是U.其中的Y是w * h,U和V是w/ ...

  6. JavaScript正则表达式(三)

    正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证 •替换文本.可以在文档中使用一个正则表达式 ...

  7. sqlserver 在脚本中,为所有字符前没有N标记的字符增加N

    {[^N]}{'[\u4e00-\u9fa5]|[\u4e00-\U9fa5]|[0-9]|[A-Z]} \1N\2

  8. JS之iframe中的窗口

    1.window.self 对当前窗口自身的引用;self,window.self,window三者是等价的 2.window.top 对顶层窗口的引用,如果本身就是顶层窗口,则返回本身 3.wind ...

  9. Selenium2学习-003-WebUI自动化实战实例-001-百度搜索

    此文主要通过百度搜索功能,进行 Selenium2 的实战实例讲解,文中所附源代码于 2015-01-16 02:01 亲测通过,敬请亲们阅览.希望能对初学 Selenium2 UI 自动化测试编程的 ...

  10. 如何在 Linux 中清除缓存(Cache)

              如何在 Linux 中清除缓存(Cache)            方法一: http://mp.weixin.qq.com/s?__biz=MjM5ODAzODgyMQ==&am ...