天天看點

android加載so過程,android 加載so的流程

源碼版本: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