首先,在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);
}
答案 0 :(得分:7)
VMStack.getCallingClassLoader()
返回声明调用当前方法的方法的类的类加载器。换句话说,如果我的函数foo()
调用Runtime.loadLibrary()
,它将返回foo
的类加载器。
所有这一切都是为了确保在调用findLibrary
的人的上下文中加载库,而不是在java.lang.Runtime
的上下文中。
findLibrary()
很有可能BaseDexClassLoader
实施DexPathList.findLibrary()
,调用nativeLibraryDirectories
来完成实际工作。有趣的一点是遍历libraryPath
,它从BaseDexClassLoader
参数初始化为PathClassLoader
构造函数(从DexClassLoader
或android.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的路径相结合。有关订购的说明,请参阅那里的评论。