android 动态加载多个so(包含so引用so)
2018-04-22 本文已影响8人
tpkeeper
0、目标so为a 被引用so为b a引用b
1、被引用的so b
- 需要有头文件,包含extern "C" 定义函数
2、生成待使用的目标so a
- cmakelist.txt 中要指定 .h头文件位置 参考:
include_directories( libs/jni/include/ )
- cmakelist.txt 中要指定被引用的so 位置 (注意路径:使用相对路径可能报错 jinjar err missing and no known rule to make it) 参考:
add_library( # Sets the name of the library.
extest-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
IMPORTED )
set_target_properties( # Specifies the target library.
extest-lib
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
D:/work/test/extest1/app/libs/jni/${ANDROID_ABI}/libextest-lib.so
)
- 配置目标依赖 参考:
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
extest-lib
${log-lib} )
3、app中使用 so
- 动态加载so ,可以so放在sdcard 任意目录,然后复制到app安装目录下,再使用system.load()执行加载。(注意加载顺序:先加载被引用的so b,再加载目标so a,否则会报错:b not found)
//防止重复加载
private List<String> loadSoList = new ArrayList<>();
public void loadSo(String name) {
Log.e("TAG","loadSo:"+name);
File file = new File("/sdcard/" + name + ".so");
String path = getDir("libs", MODE_PRIVATE).getAbsolutePath() + "/" + name + ".so";
Log.e("TAG", "getdirPath: " + getDir("libs", MODE_PRIVATE).getAbsolutePath() + "to path:" + path);
File to = new File(path);
if (!to.exists()) {
if (file.exists()) {
Log.e("TAG", "so exit");
copy(file, to);
}
}
if (!loadSoList.contains(name)) {
System.load(path);
loadSoList.add(name);
}
}
public static void copy(File from, File to) {
try {
FileInputStream fileInputStream = new FileInputStream(from);
FileOutputStream fileOutputStream = new FileOutputStream(to);
byte[] buffer = new byte[1024];
int len;
while ((len = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
4、注意事项
- ndk中配置的目录,对应的依赖so也需要提供相应的版本
ndk {
abiFilters 'arm64-v8a'
}