版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16064871/article/details/82859110
有些so文件太大,可以从手机内存或者sd卡里面拷贝到运行的应用程序里面。接口都是之前打包在里面了。还可以做so更新,就是把之前拷贝进行删除,然后进行不重新打包apk,进行重新拷贝进去。
1,封装好的类
package com.rtcmdemo.until;
import android.content.Context;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* so库从sd卡拷贝到app的私有目录下,并进行比对验证和加载
*/
public class LoadSoFileUtils {
private static String nameSO = "libSaveLib";
/**
* 加载 so 文件
*/
public static int loadSoFile(Context context, String fromPath) {
File dir = context.getDir("jniLibs", Context.MODE_PRIVATE);
String fromPathFile = fromPath + "/" + nameSO + ".so";
File isExist = new File(fromPathFile);
if (!isLoadSoFile(dir, isExist.exists())) {
return copy(fromPath, dir.getAbsolutePath());
} else {
return 0;
}
}
/**
* 判断 so 文件是否存在
*/
public static boolean isLoadSoFile(File dir, Boolean isExist) {
File[] currentFiles;
currentFiles = dir.listFiles();
boolean hasSoLib = false;
if (currentFiles == null) {
return false;
}
for (File currentFile : currentFiles) {
//判断里面是否存在这个库,以及sd也有这个库,那就删除,然后进行外面拷贝进去
if (currentFile.getName().contains(nameSO)) {
hasSoLib = isExist && !currentFile.delete();
}
}
return hasSoLib;
}
public static int copy(String fromFile, String toFile) {
//要复制的文件目录
File[] currentFiles;
File root = new File(fromFile);
//如同判断SD卡是否存在或者文件是否存在,如果不存在则 return出去
if (!root.exists()) {
return -1;
}
//如果存在则获取当前目录下的全部文件 填充数组
currentFiles = root.listFiles();
if (currentFiles == null) {
return -1;
}
//目标目录
File targetDir = new File(toFile);
//创建目录
if (!targetDir.exists()) {
targetDir.mkdirs();
}
int statue = -1;
//遍历要复制该目录下的全部文件
for (File currentFile : currentFiles) {
if (currentFile.isDirectory()) {
//如果当前项为子目录 进行递归
copy(currentFile.getPath() + "/", toFile + currentFile.getName() + "/");
} else {
//如果当前项为文件则进行文件拷贝
if (currentFile.getName().contains(".so")) {
statue = copySdcardFile(currentFile.getPath(), toFile + File.separator + currentFile.getName());
}
}
}
return statue;
}
//文件拷贝
//要复制的目录下的所有非子目录(文件夹)文件拷贝
public static int copySdcardFile(String fromFile, String toFile) {
try {
FileInputStream fosfrom = new FileInputStream(fromFile);
FileOutputStream fosto = new FileOutputStream(toFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = fosfrom.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
// 从内存到写入到具体文件
fosto.write(baos.toByteArray());
// 关闭文件流
baos.close();
fosto.close();
fosfrom.close();
return 0;
} catch (Exception ex) {
return -1;
}
}
}
2,使用方式
File dir = this.getDir("jniLibs", Activity.MODE_PRIVATE);
String ext = FilePathManage.GetInstance().getDataDirectory();
try {
LoadSoFileUtils.loadSoFile(this, ext);
File[] currentFiles;
currentFiles = dir.listFiles();
for (File currentFile : currentFiles) {
System.load(currentFile.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
注意外部加载都是使用:
System.load(currentFile.getAbsolutePath()); 里面参数就是so全路径
注意jar接口里面不要带有下面,因为会跟上面冲突。因为我们有时习惯自已编译库里面直接写了下面这个。
static{
System.loadLibrary("libSaveLib");
}
记得自已加上权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />