Android 动态加载so
与平常我们调用SO库文件不同,我们使用 System.load(String pathName);来动态加载so:
注意:1.System.load只能加载两个目录路劲下的so文件:
1、/system/lib ;需要root权限
2、安装包的路径,即:/data/data/<packagename>/…
这里我们将网络下载的so库放在根目录下 /sdcard/ ,然后将so拷贝到 私有路径下
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.content.Context;
import android.util.Log;
public class SoFileUtils {
private static final String TAG = "TAG_soUtils";
/**
* 复制文件
* @param context
* @param sourcePath 资源路径 /sdcard/libhellojin.so
* @param destPath 目标路径
* @return
*/
public static boolean copyFile(String sourcePath, String destPath){
File sourceFile = new File(sourcePath);
if(!sourceFile.exists()){
Log.e(TAG, "so文件不存在,请检查sd卡上是否已下载");
return false;
}
File destFile = new File(destPath);
// 目标so存在,删除
if(destFile.exists())
destFile.delete();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(sourceFile));
bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] buff = new byte[1024 * 8];
int len = 0;
while((len = bis.read(buff)) > 0){
bos.write(buff, 0, len);
}
} catch (IOException e) {
return false;
} finally {
if (null != bos)
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
if (null != bis)
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
}
然后在需要调用的地方执行:
try {
String sourcePath = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+ "libHelloJni.so";
Log.i("TAG", "sourcePath:"+sourcePath);
String destPath = getDir("libs", Context.MODE_PRIVATE).getAbsolutePath()+ File.separator+ "libHelloJni.so";
Log.i("TAG", "destPath:"+destPath);
if(SoFileUtils.copyFile(sourcePath, destPath)){
System.load(destPath);
// do what you want
}
} catch (Exception e) {
e.printStackTrace();
}