android 加载三方so的方法_Android动态加载so文件(解决so文件冲突)

本文介绍了在Android开发中如何处理第三方库SO文件冲突的问题,通过动态加载的方式避免静态加载时的冲突。详细阐述了动态加载的实现过程,包括从assets目录拷贝SO文件到本地数据目录,并在需要时初始化指定路径的SDK。
摘要由CSDN通过智能技术生成

在开发过程中,经常会用到第三方库,比如地图、视频、文档编辑、图表之类。依赖这些库,需要添加其SDK,有时需要用到jni层的So文件,比如百度地图等。

那么问题来了,如果两个不同的库之间的so文件发生冲突这么办?

比如:单独添加地图的库,运行没有问题。单独添加一个视频库,运行没有问题。但两者同时添加,其中一个库在init的时候报错。这当然和第三方库的开发水平有很大关系,但我们怎么解决这个问题呢?这就用到动态加载的方法。

这是原先的静态加载方法,将所有依赖库的so文件全部一股脑的放进armeabi文件夹即可。

静态加载

动态加载的方法,我将冲突的so文件放在assets文件夹中

动态加载

这里需要注意的是:动态加载so的文件只能放在两个地方:1. lib文件夹中,即对应Android Studio中的jniLibs文件夹。2. 本地data/data/package数据目录下。 所以,当应用第一次启动的时候,必须将我们放在assets文件夹中的so文件拷贝乳本地数据目录下。

//每次进入app,遍历assets目录下所有的文件,是否在data/data目录下都已经存在,不存在则拷贝

private void initAssetsFile() {

boolean needCopy = false;

// 创建data/data目录

File file = getApplicationContext().getFilesDir();

String path = file.toString() + "/armeabi/";

// 遍历assets目录下所有的文件,是否在data/data目录下都已经存在

try {

String[] fileNames = getApplicationContext().getAssets().list("armeabi");

for (int i = 0; fileNames != null && i < fileNames.length; i++) {

if (!TFileUtils.isFileExit(path + fileNames[i])) {

needCopy = true;

break;

}

}

} catch (IOException e) {

e.printStackTrace();

}

if (needCopy) {

CommonUtils.copyFilesFassets(getApplicationContext(), "armeabi", path);

}

}

//将旧目录中的文件全部复制到新目录

public static void copyFilesFassets(Context context, String oldPath, String newPath) {

try {

// 获取assets目录下的所有文件及目录名

String fileNames[] = context.getAssets().list(oldPath);

// 如果是目录名,则将重复调用方法递归地将所有文件

if (fileNames.length > 0) {

File file = new File(newPath);

file.mkdirs();

for (String fileName : fileNames) {

copyFilesFassets(context, oldPath + "/" + fileName, newPath + "/" + fileName);

}

}

// 如果是文件,则循环从输入流读取字节写入

else {

InputStream is = context.getAssets().open(oldPath);

FileOutputStream fos = new FileOutputStream(new File(newPath));

byte[] buffer = new byte[1024];

int byteCount = 0;

while ((byteCount = is.read(buffer)) != -1) {

fos.write(buffer, 0, byteCount);

}

fos.flush();

is.close();

fos.close();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//在需要初始化SDK的地方,指定so文件的路径

private void initAPI() {

File file = getApplicationContext().getFilesDir();

String path = file.toString() + "/armeabi/";

EzvizAPI.init(getApplication(), key, path);

}

当然,上面这个方法是将so文件放在程序的assets文件夹。另一种方法是:也可以从网络上下载,放入本地数据目录下。这样的好处是不仅减小的了apk的大小,而且可以随时使用最新的依赖库,这也是动态加载的最多得用途之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值