dalvik如何找到图书馆?

时间:2013-03-29 10:55:56

标签: 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());
}

第二,它将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");
        }
        //....
    }
}

所以,我认为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);
}

1 个答案:

答案 0 :(得分:7)

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

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

findLibrary()很有可能BaseDexClassLoader实施DexPathList.findLibrary(),调用nativeLibraryDirectories来完成实际工作。有趣的一点是遍历libraryPath,它从BaseDexClassLoader参数初始化为PathClassLoader构造函数(从DexClassLoaderandroid.app.ApplicationLoaders获取)

对于Android应用,请查看使用PathClassLoader的{​​{1}}。如果您追溯到足够远,您将看到从ApplicationInfo.nativeLibraryDir检索的目录。

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

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

PackageManagerService构造函数在mAppLibInstallDir中设置lib路径,setInternalAppNativeLibraryPath()配置nativeLibraryDir

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