Android so lib库远程http下载和动态注册
一、背景
在开发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下载和动态注册的更多相关文章
- android多lib库工程的自动批量构建--准备
打包这个活儿吧,本来没什么技术含量,千篇一律的更改渠道名称,然后编译,签名即可.但是如果发布渠道比较多的话,这种重复工作让人烦不胜烦.我们的应用发布渠道有30多个,若是手工打包,基本不用做其他的事情了 ...
- android多lib库工程的自动批量构建--编写ant脚本
基本配置--build.properties 首先编写基本配置build.properties ,主要配置如下: android sdk所在目录 编译项目所使用的项目版本 Jdk所在目录 以及签名时, ...
- Android 动态注册JNI函数
1.JNI函数注册方式 在Android开发中,由于种种原因我们需要调用C/C++代码,在这个时候我们就需要使用jni了, jni在使用时要对定义的函数进行注册,这样java才能通过native关键字 ...
- Android只能动态注册的广播Action
只能动态注册的广播(部分): android.intent.action.SCREEN_ON android.intent.action.SCREEN_OFF android.intent.actio ...
- 解决android studio引用远程仓库下载慢(转)
解决android studio引用远程仓库下载慢(JCenter下载慢) 第一种方法 使用开源中国的maven库 阿里云的(速度飞快):http://maven.aliyun.com/nexus/c ...
- 如何把一个android工程作为另外一个android工程的lib库
http://zhidao.baidu.com/question/626166873330652844 一个工程包含另一个工程.相当于一个jar包的引用.但又不是jar包反而像个package 在网上 ...
- android studio 引用远程仓库下载慢(JCenter下载慢)的办法
https://blog.csdn.net/linglingchenchen/article/details/62236723 解决android studio引用远程仓库下载慢(JCenter下载慢 ...
- android 如何添加第3方lib库到kernel中
注意:只能将lib库放在kernel编译到的地方,如下: alps/kernel/ alps/mediatek/custom/common/kernel/ alps/mediatek/custom/$ ...
- Android Studio提交库至Bintray jCenter从入门到放弃
文:http://blog.csdn.net/sk719887916/article/details/52473914 作者:Tamic 详细文章请看:[Gradle系列]Gradle发布module ...
随机推荐
- 地图API使用文档-以腾讯地图为例
目录 腾讯地图API 2 1.API概览... 2 1.1 WebService API(官网注明是beta版本,可能不稳定,慎用):... 2 1.2 URL API:... 2 1.3 静态图AP ...
- gtd好文两篇收藏
http://www.jianshu.com/p/bf5e8a9761f5 http://blog.sina.com.cn/s/blog_4e0f66b80100m73i.html
- Java高级之内存模型分析
博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 下文是博主感悟,请带着怀疑性的态度阅读! 需要了解基本变量所占 ...
- 关于java字符串编译优化问题
情景一:不好的字符串拼接习惯 起因是这样的:一个大牛在写了一篇关于java字符串优化问题的讲解,他提到:不要使用strObj+otherValue的方法将otherValue转换为字符串形式,因 ...
- Mixing Delphi and C++(相互调用)
Mixing Delphi and C++ You have a TStringList and <algorithm>. What can you do? Quite a lot, ac ...
- 使用多种客户端消费WCF RestFul服务(二)——.net4.0篇
.net 4.0篇 在.net 4.0下面微软并没有提供类似Net.Http的Rest访问组件,而是在codeplex上面提供的WCF REST Starter Kit Preview 2 里面可以找 ...
- Cocos2d-JS切换场景与切换特效
var HelloWorldLayer = cc.Layer.extend({ sprite:null, ctor:function () { //////////////////////////// ...
- 解决父类加载iframe,src参数过大导致加载失败
原文:解决父类加载iframe,src参数过大导致加载失败 <iframe src="*******.do?param=****" id="leftFrame&qu ...
- ArcGIS API for JavaScript开发环境搭建及第一个实例demo
原文:ArcGIS API for JavaScript开发环境搭建及第一个实例demo ESRI公司截止到目前已经发布了最新的ArcGIS Server for JavaScript API v3. ...
- DiG HOWTO How to use dig to query DNS name servers.
Contents Introduction Understanding the default output What can I discover? How do I … Get a short a ...