您的位置:首页 > 其它

System.loadLibrary调用SO源码解析

2017-09-03 15:25 477 查看

首先跟着源码走

System.loadLibrary(“native-lib”)

在loadLibrary里面会调用[b]Runtime.getRuntime().loadLibrary0()方法,里面有两个参数VMStack.getCallingClassLoader()和libname[/b]

Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), libname);

继续在Runtime类中会找到loadLibrary0方法

synchronized void loadLibrary0(ClassLoader loader, String libname) {
if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError(
"Directory separator should not appear in library name: " + libname);
}
String libraryName = libname;
if (loader != null) {
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".
throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
System.mapLibraryName(libraryName) + "\"");
}
String error = doLoad(filename, loader);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
return;
}

String filename = System.mapLibraryName(libraryName);
List<String> candidates = new ArrayList<String>();
String lastError = null;
for (String directory : getLibPaths()) {
String candidate = directory + filename;
candidates.add(candidate);

if (IoUtils.canOpenReadOnly(candidate)) {
String error = doLoad(candidate, loader);
if (error == null) {
return; // We successfully loaded the library. Job done.
}
lastError = error;
}
}

if (lastError != null) {
throw new UnsatisfiedLinkError(lastError);
}
throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
}


这里面有个判断,判断ClassLoader在不在,一般都是有的所以会进入,这里面有个重要 的方法 loader.findLibrary(libraryName);当我们点进去的时候发现返回的是NULL

protected String findLibrary(String libname) {
return null;
}


这样我们就想到了,他还会有子类于是我们通过LOG打印出当前的ClassLoader

Log.d(TAG,"ClassLoader ++"+this.getClassLoader().toString());

//   这是打印的子类dalvik.system.PathClassLoader


于是我们翻看Android源码7.1.1(有5.23个G已下载好)PathClassLoader类,发现没有实现太多。于是我们找到了他的父类BaseDexClassLoader的findLibrary()方法

他这里面返回了pathList.findLibrary(name)
@Override
public String findLisbrary(String name){
return pathList.findLibrary(name);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: