一 概述
System.loadLibrary("jpeg"):加载动态库名称如libjpeg
System.load("D:\java\Test.so");记载绝对路径
二 System.load源码分析
//System类
public static void load(String filename) {
//Reflection.getCallerClass()返回的是当前调用类的字节码Class
Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
}
//Runtime类
synchronized void load0(Class> fromClass, String filename) {
//1.判断是否是绝对路径,即路径中是否包含'/'
if (!(new File(filename).isAbsolute())) {
throw new UnsatisfiedLinkError(
"Expecting an absolute path of the library: " + filename);
}
if (filename == null) {
throw new NullPointerException("filename == null");
}
//2.调用 nativeLoad进行加载动态库,参数是文件路径和ClassLoader对象
String error = nativeLoad(filename, fromClass.getClassLoader());
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
}
三 System.loadLibrary源码解析
//System类
public static void loadLibrary(String libname) {
Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
}
//Runtime类
void loadLibrary0(Class> fromClass, String libname) {
//获取当前类的ClassLoader,在android中一般是PathClassLoader
ClassLoader classLoader = ClassLoader.getClassLoader(fromClass);
loadLibrary0(classLoader, fromClass, libname);
}
private synchronized void loadLibrary0(ClassLoader loader, Class> callerClass, String libname) {
if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(
"Directory separator should not appear in library name: " + libname);
}
String libraryName = libname;
//1.判断classLoader是否为null以及是否是BootClassLoader实例
if (loader != null && !(loader instanceof BootClassLoader)) {
//2.调用classLoader.findLibrary(libraryName)方法查找so库文件
String filename = loader.findLibrary(libraryName);
if (filename == null) {
// It's not necessarily true that the ClassLoader used
// System.mapLibraryName, but the default setup does, and it's
// misleading to say we didn't find "libMyLibrary.so" when we
// actually searched for "liblibMyLibrary.so.so".
// 3.翻译:加载so的时候不要传lib以及后缀名so,否则会变成查找liblibMyLibrary.so.so
throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
System.mapLibraryName(libraryName) + "\"");
}
//4.最终也会通过jni调用nativeLoad加载动态库
String error = nativeLoad(filename, loader);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
return;
}
// We know some apps use mLibPaths directly, potentially assuming it's not null.
// Initialize it here to make sure apps see a non-null value.
// 如果classLoader为null,执行的逻辑,从system.java.library中查找
getLibPaths();
String filename = System.mapLibraryName(libraryName);
// 最终还是调用nativeLoad方法。
String error = nativeLoad(filename, loader, callerClass);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
}
public static native java.lang.String mapLibraryName(java.lang.String libname);
这里根据ClassLoader是否存在分了两种情况,当ClasssLoader存在的时候通过loader的findLibrary()查看目标库所在路径,当ClassLoader不存在的时候通过mLibPaths加载路径。最终都会调用nati