什么是Android Linker
Android 的加载/链接器linker 主要用于实现共享库的加载与链接。
从 System.loadLibrary 追溯
jni 开发的 so load
平时我们进行JNI开发 要链接我们的so库只需要执行System.loadLibrary
函数即可
static {
try {
CLogUtils.e("开始加载 Test so文件 ");
System.loadLibrary("Test");
init();
} catch (Throwable e) {
CLogUtils.e("加载So出现异常 " + e.toString());
e.printStackTrace();
}
}
或许你没有想过 为什么这样就可以将so加载进来了。
我们继续跟进代码
本次采用SDK28的代码 也就是安卓9.0的代码分析
System.loadLibrary("Test");
->Runtime loadLibrary0
loadLibrary0方法跟进
...
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 = nativeLoad(candidate, loader);
if (error == null) {
return; // We successfully loaded the library. Job done.
}
lastError = error;
}
}
...
走到了 nativeLoad 方法
nativeLoad
private static native String nativeLoad(String filename, ClassLoader loader);
显然是一个Native方法
我们要找到他对应的cpp代码。通过查找资料得知他的文件路径在
libcore/ojluni/src/main/native/Runtime.c
打开源码阅读网站分析:
runtime.c
核心的代码部分
JNIEXPORT jstring JNICALL
Runtime_nativeLoad(JNIEnv* env, jclass ignored, jstring javaFilename,
jobject javaLoader)
{
return JVM_NativeLoad(env, javaFilename, javaLoader);
}
转到了 JVM_NativeLoad(env, javaFilename, javaLoader);
方法中
JVM_NativeLoad
这个方法在libcore/ojluni/src/main/native/jvm.h
中
方法申明
JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename,
jobject javaLoader);
具体的方法实现要看谁实现这个方法申明
art/openjdkjvm/OpenjdkJvm.cc
JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env,
jstring javaFilename,
jobject javaLoader) {
ScopedUtfChars filename(env, javaFilename);
if (filename.c_str() == NULL) {
return NULL;
}
std::string error_msg;
{
art::JavaVMExt* vm = art::Runtime::Current()->