源碼版本:android-4.4.4_r1
以 [java.lang.Runtime -> load()] 為例來說明(loadLiabrary() 最後和 load() 殊途同歸,有興趣的可以自行分析),對應的 Android 源碼在 [srcAndroid/libcore/luni/src/main/java/java/lang/Runtime.java/home/shanyu/srcAndroid/libcore/luni/src/main/java/java/lang/Runtime.java],
從 320 行開始。
public voidload(String pathName) {
load(pathName, VMStack.getCallingClassLoader());
}
voidload(String pathName, ClassLoader loader) {if (pathName == null) {throw new NullPointerException("pathName == null");
}
String error=doLoad(pathName, loader);if (error != null) {throw newUnsatisfiedLinkError(error);
}
}
最終調用了doLoad(String name, ClassLoader loader)函數,這個函數仍然在Runtime.java檔案中:
privateString doLoad(String name, ClassLoader loader) {//Android apps are forked from the zygote, so they can‘t have a custom LD_LIBRARY_PATH,//which means that by default an app‘s shared library directory isn‘t on LD_LIBRARY_PATH.//The PathClassLoader set up by frameworks/base knows the appropriate path, so we can load//libraries with no dependencies just fine, but an app that has multiple libraries that//depend on each other needed to load them in most-dependent-first order.//We added API to Android‘s dynamic linker so we can update the library path used for//the currently-running process. We pull the desired path out of the ClassLoader here//and pass it to nativeLoad so that it can call the private dynamic linker API.//We didn‘t just change frameworks/base to update the LD_LIBRARY_PATH once at the//beginning because multiple apks can run in the same process and third party code can//use its own BaseDexClassLoader.//We didn‘t just add a dlopen_with_custom_LD_LIBRARY_PATH call because we wanted any//dlopen(3) calls made from a .so‘s JNI_OnLoad to work too.//So, find out what the native library search path is for the ClassLoader in question...
String ldLibraryPath = null;if (loader != null &&loader instanceof BaseDexClassLoader) {
ldLibraryPath=((BaseDexClassLoader) loader).getLdLibraryPath();
}//nativeLoad should be synchronized so there‘s only one LD_LIBRARY_PATH in use regardless//of how many ClassLoaders are in the system, but dalvik doesn‘t support synchronized//internal natives.
synchronized (this) {returnnativeLoad(name, loader, ldLibraryPath);
}
}//TODO: should be synchronized, but dalvik doesn‘t support synchronized internal natives.
private static native String nativeLoad(String filename, ClassLoader loader, String ldLibraryPath);
最終調用到了"String nativeLoad(String filename, ClassLoader loader, String ldLibraryPath)"函數,這個一個native函數,定義位于[srcAndroid/dalvik/vm/native/java_lang_Runtime.cpp]檔案中。從64行開始:
static void Dalvik_java_lang_Runtime_nativeLoad(const u4*args,
JValue*pResult)
{
StringObject* fileNameObj = (StringObject*) args[0];
Object* classLoader = (Object*) args[1];
StringObject* ldLibraryPathObj = (StringObject*) args[2];
assert(fileNameObj!=NULL);char* fileName =dvmCreateCstrFromString(fileNameObj);if (ldLibraryPathObj !=NULL) {char* ldLibraryPath =dvmCreateCstrFromString(ldLibraryPathObj);void* sym = dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH");if (sym !=NULL) {
typedefvoid (*Fn)(const char*);
Fn android_update_LD_LIBRARY_PATH= reinterpret_cast(sym);
(*android_update_LD_LIBRARY_PATH)(ldLibraryPath);
}else{
ALOGE("android_update_LD_LIBRARY_PATH not found; .so dependencies will not work!");
}free(ldLibraryPath);
}
StringObject* result =NULL;char* reason =NULL;bool success = dvmLoadNativeCode(fileName, classLoader, &reason);if (!success) {const char* msg = (reason != NULL) ? reason : "unknown failure";
result=dvmCreateStringFromCstr(msg);
dvmReleaseTrackedAlloc((Object*) result, NULL);
}free(reason);free(fileName);
RETURN_PTR(result);
}
還是傳值 + 檢查,然後執行 [bool success = dvmLoadNativeCode(fileName, classLoader, &reason);] ,看下 dvmLoadNativeCode(...) 的代碼,位于 vm/Native.cpp # 301 行。
原文:http://www.cnblogs.com/xunbu7/p/6898913.html