Where and when is the PathClassLoader instance created in Android source code?

When I was looking into the Android source code, I noticed that the generic classloader in the application is instance PathClassLoader

and there are two constructors in this class. One is like this:

 public PathClassLoader(String dexPath, ClassLoader parent) {
     super(dexPath, null, null, parent);
 }

      

and the other is like:

  public PathClassLoader(String dexPath, String libraryPath,
          ClassLoader parent) {
      super(dexPath, null, libraryPath, parent);
  }

      

But I cannot find the call to the second constructor in the source code during the application startup routine. So where does the value of the libraryPath param come from? As you know, libraryPath refers to a list of directories containing native libraries and is used to initialize a value nativeLibraryDirectories

that is a field of a DexPathList object. So, if there is no call to the second constructor with three parameters, how can the value be initialized nativeLibraryDirectories

? So how can an application find its own libraries?

Actually, I'm wondering who determines the value of nativeLibraryDirectories?

Hope someone can help me with this. Many thanks.

+3


source to share


1 answer


So where did the libraryPath param value come from ?

You can use search in Android Studio to find it. Execute "Find in Path" specifying the "Scope" parameter to the Android sources directory. A regular expression follows as the text to search for insertion:

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

      

This corresponds to calling a constructor with three parameters. Also, don't forget to check the Regular Expression checkbox:

enter image description here

Then, in the preview tab, you should be able to see the results:

enter image description here

Using the same technique, you can find out who is calling the function PathClassLoaderFactory#createClassLoader()

:



enter image description here

In ZygoneInit.java

you can find the following piece of code:


    /**
     * 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 */);
    }

      

Now back to your questions.

So if there is no call to the second constructor with three parameters ...

There is a ZygoteInit#handleSystemServerProcess()

call createSystemServerClassLoader()

that will eventually call the 3 args constructors PathClassLoader

.

Actually I'm wondering who defines the nativeLibraryDirectories value ?

As you can see from the above code, the system property is used by default "java.library.path"

.

+1


source







All Articles