dalvik如何找到图书馆?

use*_*819 2 android dalvik

首先,在System.java中,它将Runtime调用为loadLibrary.

public static void loadLibrary(String libName) {
    SecurityManager smngr = System.getSecurityManager();
    if (smngr != null) {
        smngr.checkLink(libName);
    }
    Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
}
Run Code Online (Sandbox Code Playgroud)

第二,它将VMStack.getCallingClassLoader()调用到findLibrary.

void loadLibrary(String libraryName, ClassLoader loader) {
    if (loader != null) {
        String filename = loader.findLibrary(libraryName);
        if (filename == null) {
            throw new UnsatisfiedLinkError("Couldn't load " + libraryName + ": " +
                    "findLibrary returned null");
        }
        //....
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我认为VMStack.getCallingClassLoader()是最有意义的.但是在其jni文件dalvik_system_VMStack.cpp中,该Dalvik_dalvik_system_VMStack_getCallingClassLoader功能很难学习.最后,dalvik如何找到图书馆?

static void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args,
    JValue* pResult){
    ClassObject* clazz =
        dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);

    UNUSED_PARAMETER(args);

    if (clazz == NULL)
        RETURN_PTR(NULL);
    RETURN_PTR(clazz->classLoader);
}
Run Code Online (Sandbox Code Playgroud)

fad*_*den 7

VMStack.getCallingClassLoader()返回声明调用当前方法的方法的类的类加载器.换句话说,如果foo()调用我的函数Runtime.loadLibrary(),它将返回foo类加载器.

所有这一切都是为了确保库在被调用者的上下文中加载findLibrary,而不是在上下文中java.lang.Runtime.

有一个很好的机会findLibrary()实现BaseDexClassLoader,它调用DexPathList.findLibrary(),实际工作.有趣的一点是walk through nativeLibraryDirectories,它从构造函数的libraryPath参数初始化BaseDexClassLoader(从PathClassLoader或获取它DexClassLoader).

对于Android应用,请看一下android.app.ApplicationLoaders,它使用的是PathClassLoader.如果你追溯到足够远,你会看到从中检索的目录ApplicationInfo.nativeLibraryDir.

编辑:更深入地发表评论......

/system/lib来自java.library.path属性,核心库从LD_LIBRARY_PATH环境变量中提取.特定于应用程序的库dir由框架配置.

PackageManagerService构造函数设置在lib路径mAppLibInstallDir,并setInternalAppNativeLibraryPath()提供配置nativeLibraryDir.

DexPathList.splitLibraryPath()java.library.path路径与特定于APK 的路径组合在一起.有关订购的说明,请参阅那里的评论.