5

Android动态加载so文件(解决so文件冲突)

 3 years ago
source link: http://www.androidchina.net/4580.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Android动态加载so文件(解决so文件冲突) – Android开发中文站
你的位置:Android开发中文站 > Android开发 > 开发进阶 > Android动态加载so文件(解决so文件冲突)

在开发过程中,经常会用到第三方库,比如地图、视频、文档编辑、图表之类。依赖这些库,需要添加其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的大小,而且可以随时使用最新的依赖库,这也是动态加载的最多得用途之一。

转载请注明:Android开发中文站 » Android动态加载so文件(解决so文件冲突)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK