一、背景
在开发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开发文章