当前位置: 代码迷 >> Android >> Android so lib库远路http下载和动态注册
  详细解决方案

Android so lib库远路http下载和动态注册

热度:83   发布时间:2016-04-28 02:58:51.0
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
?????* 下载文件到/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文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 KSOAP2调用.net webservice

jQuery教程(8)-DOM树操作之使用反向插入方法

android学习笔记(34)使用AlertDialog创建简单对话框

android学习笔记(33)画廊视图(Gallery)的功能和用法

android navidgation drawer 在导航抽屉中如何改变List选中项的...

?

更多关于android开发文章

  相关解决方案