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.
source to share
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:
Then, in the preview tab, you should be able to see the results:
Using the same technique, you can find out who is calling the function PathClassLoaderFactory#createClassLoader()
:
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"
.
source to share