在Android源代码中创建的PathClassLoader实例的位置和时间是什么?

时间:2017-03-24 03:31:36

标签: java android classloader abi nativelibrary

当我研究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的价值?

希望有人可以指导我。非常感谢。

1 个答案:

答案 0 :(得分:1)

  

那么 libraryPath param的价值来自哪里?

您可以使用Android Studio搜索找到它。执行“在路径中查找”,为Android源目录指定“Scope”参数。作为在regex表达式后找到粘贴的文本:

new PathClassLoader\(\w+, \w+, \w+\)\;

这匹配构造函数的调用与三个参数。另外,不要忘记检查“正则表达式”复选框:

enter image description here

然后在预览标签中,您将能够看到结果:

enter image description here

使用相同的技术,您可以找出谁正在调用PathClassLoaderFactory#createClassLoader()函数:

enter image description here

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"