一、背景
在开发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选中项的...
相关推荐
本教程将详细解释如何将C编写的动态链接库(.so文件,即lib库)整合到Android应用中,并打包成APK进行安装。 1. **创建JNI接口** 在Java代码中,我们需要定义JNI接口,这些接口将被C/C++代码实现。使用`native`...
这些库分为静态库(如liblive555.a)和动态库(如liblive555.so或.dll),选择哪种取决于你的需求。静态库会将所有依赖项打包进你的可执行文件,而动态库则会在运行时从系统中加载。 **3. RTSP、RTP和RTCP** - **...
在Android系统中,SO(Shared Object)文件,也被称为动态链接库,是开发者用来实现特定功能,特别是硬件接口、加密算法、性能优化等关键部分的二进制代码。本资料"Android so加载深入分析.pdf"将详细探讨Android...
SO文件是Shared Object的简称,在Linux或类Unix系统中通常用于实现动态链接库的功能。在Android开发中,SO文件主要用于封装用C或C++编写的原生代码。这些文件通常存储在`/system/lib`或`/system/lib64`目录下,并由...
2. **SO文件(Shared Object)**:这是动态链接库,包含了WebRTC的C++实现,负责处理底层的音视频编码、解码以及网络传输等任务。Android应用在运行时会加载这些库来执行实际的通信操作。 3. **示例代码和文档**:...
SO库是Linux系统下的动态链接库,对应于Windows平台上的DLL。在Android中,.so文件是NDK编译产生的,包含了C/C++代码。JNI是Java和本地代码之间的桥梁,它定义了一套接口,使得Java代码可以通过这些接口调用本地函数...
libjingle_peerconnection是Android WebRTC的核心库,提供了P2P(点对点)通信的基础框架,包括ICE(Interactive Connectivity Establishment)用于网络连接,STUN(Session Traversal Utilities for NAT)和TURN...
由于OpenSSH依赖于zlib和openssl库,所以我们需要先编译zlib和openssl库。我们可以使用以下命令编译zlib和openssl:`$source build/envsetup.sh` `$mmm -B external/zlib` `$mmm -B external/openssl` 之后,我们...
在Android环境中,由于安全和沙箱化的考虑,程序通常以PIE(Position Independent Executable)模式编译,这使得动态地址分配,增加了逆向工程和调试的难度。不过,通过GDB和GDBserver,我们可以远程调试运行在设备...
- 在Java层创建一个静态块,使用`System.loadLibrary("native-lib")`加载动态链接库。 - 在C/C++代码中,`RegisterNatives()`函数或`JNI_OnLoad()`可以用来自动注册JNI函数。 7. **构建和调试** - 使用Android ...
使用NDK构建系统(如Android Studio中的CMake),将C++代码编译成.so动态库文件,并将其打包进APK的`lib`目录下,对应不同的CPU架构。 8. **内存管理**: Java和C++的内存管理机制不同,需要特别注意内存泄漏问题...
sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so ``` 此外,还需安装`uuid`、`uuid-dev`、`zlib1g-dev`和`liblz-dev`,以及`liblzo2-2`和`liblzo2-dev`,以确保编译过程的...
### OpenSSH移植到Android系统的详细步骤 #### 一、获取OpenSSH源码 为了将OpenSSH移植到Android...通过上述步骤,OpenSSH可以在Android设备上运行,并支持密钥认证登录,从而实现了对Android系统的远程访问功能。
- **动态库加载**:应用程序必须明确加载对应的动态库,通常这个动态库会被命名为`lib<something>.so`。加载示例代码如下: ```java static { System.loadLibrary("FileLoader"); } ``` 注意这里不要加上“lib...
为了在Android原生项目中使用这个Flutter库,我们需要将生成的`flutter.jar`和`lib`目录添加到Android项目的`jniLibs`目录。假设你的Android项目结构如下: ``` your_android_project/ app/ src/ main/ jniLibs...
2. **lib**:存放库文件,如动态链接库(.so)或静态链接库(.a),这些库文件是Android应用程序在运行时依赖的。 3. **include**:包含头文件,供开发者在编写Android应用时进行编译时链接,以使用Live555的功能。 4. *...
3. `libandroid-support.so` 是Termux为Android平台提供的支持库,它包含了一些在Android系统上运行Linux程序所必需的函数和API。 4. `python.tar` 是一个打包文件,可能包含了Python的源码或者其他相关文件,解压后...
同时,可能还需要配置`sysroot`,指定Android系统的根目录,以便编译器知道如何处理系统头文件和库。 7. **构建流程**:使用Android.mk或CMakeLists.txt文件定义构建规则,通过NDK的`ndk-build`或CMake命令进行编译...
开发者可以使用NDK编译C、C++代码,生成.so动态链接库,这些库可以在Android设备上运行。 3. **构建.so库**:在“JniLibrary”项目中,开发者会编写C/C++源文件,然后使用NDK的交叉编译工具链来构建针对不同架构...
- 在Shared Libraries子页,添加`out/target/product/generic/symbols/system/lib`及其子目录,确保所有必要的库文件都被包含。 - 在Connection子页,主机名保持localhost,端口号可设置为5039。 3. **启动调试**...