When I was studying android source code, I noticed that the general class loader in app is an instance of PathClassLoader
, and there is two constructors in this class. One is like:
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 of the second constructor in the source code during the procedure of app launching. So where does the value of libraryPath param come from? As it is known that libraryPath refers to the list of directories containing native libraries, and is used for initializing the value of nativeLibraryDirectories
, which is a field of DexPathList object. So if there is no call of the second constructor with three params, how can the value of nativeLibraryDirectories
be initialized? Therefore how can an app find its native libraries?
Actually, I am wondering who determines the value of nativeLibraryDirectories?
Hope some one can guide me in this. Thanks a lot.
You can use Android Studio search to find it out. Perform "Find in Path", specifying the "Scope" parameter to directory of Android sources. As a text to find paste following regex expression:
This matches a call of the constructor with three params. Also, do not forget to check "Regular expression" checkbox:
Then in the preview tab you'll be able to see the results:
With the same technique you can find out who is calling
PathClassLoaderFactory#createClassLoader()
function:In
ZygoneInit.java
you'll be able to locate following piece of code:Now, back to your questions.
There is,
ZygoteInit#handleSystemServerProcess()
callscreateSystemServerClassLoader()
, which would eventually call 3 args constructor ofPathClassLoader
.As you can see from the code above, it defaults to system property
"java.library.path"
.