首页 > 代码库 > 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 行开始。
/** * Loads and links the dynamic library that is identified through the * specified path. This method is similar to {@link #loadLibrary(String)}, * but it accepts a full path specification whereas {@code loadLibrary} just * accepts the name of the library to load. * * @param pathName * the absolute (platform dependent) path to the library to load. * @throws UnsatisfiedLinkError * if the library can not be loaded. */ public void load(String pathName) { load(pathName, VMStack.getCallingClassLoader()); } /* * Loads and links the given library without security checks. */ void load(String pathName, ClassLoader loader) { if (pathName == null) { throw new NullPointerException("pathName == null"); } String error = doLoad(pathName, loader); if (error != null) { throw new UnsatisfiedLinkError(error); } }
最终调用了doLoad(String name, ClassLoader loader)函数,这个函数仍然在Runtime.java文件中:
private String 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) { return nativeLoad(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 String nativeLoad(String filename, ClassLoader loader, String ldLibraryPath) * * Load the specified full path as a dynamic library filled with * JNI-compatible methods. Returns null on success, or a failure * message on failure. */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) { typedef void (*Fn)(const char*); Fn android_update_LD_LIBRARY_PATH = reinterpret_cast<Fn>(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 行。
android 加载so的流程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。