当我研究android源代码时,我注意到app中的通用类加载器是PathClassLoader
的一个实例,并且这个类中有两个构造函数。一个是:
public PathClassLoader(String dexPath, ClassLoader parent) {
super(dexPath, null, null, parent);
}
另一个是:
public PathClassLoader(String dexPath, String libraryPath,
ClassLoader parent) {
super(dexPath, null, libraryPath, parent);
}
但是在app启动过程中我无法在源代码中找到第二个构造函数的调用。那么libraryPath参数的价值来自哪里呢?众所周知, libraryPath 是指包含本机库的目录列表,用于初始化nativeLibraryDirectories
的值,该值是DexPathList对象的字段。因此,如果第二个构造函数没有调用三个参数,那么nativeLibraryDirectories
的值如何初始化?因此,应用程序如何找到其本机库?
实际上,我想知道谁来决定nativeLibraryDirectories的价值?
希望有人可以指导我。非常感谢。
答案 0 :(得分:1)
那么 libraryPath param的价值来自哪里?
您可以使用Android Studio搜索找到它。执行“在路径中查找”,为Android源目录指定“Scope”参数。作为在regex表达式后找到粘贴的文本:
new PathClassLoader\(\w+, \w+, \w+\)\;
这匹配构造函数的调用与三个参数。另外,不要忘记检查“正则表达式”复选框:
然后在预览标签中,您将能够看到结果:
使用相同的技术,您可以找出谁正在调用PathClassLoaderFactory#createClassLoader()
函数:
在ZygoneInit.java
中,您将能够找到以下代码:
/**
* Creates a PathClassLoader for the system server. It also creates
* a shared namespace associated with the classloader to let it access
* platform-private native libraries.
*/
private static PathClassLoader createSystemServerClassLoader(String systemServerClasspath,
int targetSdkVersion) {
String librarySearchPath = System.getProperty("java.library.path");
return PathClassLoaderFactory.createClassLoader(systemServerClasspath,
librarySearchPath,
null /* libraryPermittedPath */,
ClassLoader.getSystemClassLoader(),
targetSdkVersion,
true /* isNamespaceShared */);
}
现在,回到你的问题。
所以如果第二个构造函数没有调用三个参数...
有ZygoteInit#handleSystemServerProcess()
次调用createSystemServerClassLoader()
,最终会调用PathClassLoader
的3个args构造函数。
实际上,我想知道谁来决定 nativeLibraryDirectories 的价值?
从上面的代码中可以看出,它默认为系统属性"java.library.path"
。