安卓高手之路之ClassLoader(三),安卓classloader
由於看C++和C代碼看得很累,很辛苦。上一章終於解脫到java代碼中來了。 第一個getClassLoader發生在main的preload方法中,
public static void main(String argv[]) {
preload();
}
Java代碼
- static void preload() {
- preloadClasses();
- preloadResources();
- }
Java代碼
- private static void preloadClasses() {
- final VMRuntime runtime = VMRuntime.getRuntime();
-
- InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
- PRELOADED_CLASSES);
可以看到,直接調用了getClassLoader()這個classLoader是個什麼東西呢。
Java代碼
- public ClassLoader getClassLoader() {
- if (this.isPrimitive()) {
- return null;
- }
-
- ClassLoader loader = getClassLoaderImpl();
- if (loader == null) {
- loader = BootClassLoader.getInstance();
- }
- return loader;
- }
由於這個類是沒有classloader的,因此調用的是BootClassLoader.getInstance().
Java代碼
- /**
- * Provides an explicit representation of the boot class loader. It sits at the
- * head of the class loader chain and delegates requests to the VM's internal
- * class loading mechanism.
- */
- class BootClassLoader extends ClassLoader {
現在明白了吧。BootClassLoader原來就是第一個class的ClassLoader。對於Zygote是com.android.internal.os.ZygoteInit,對於其他的,那就是com.android.internal.os.RuntimeInit 的classloader。也就是init.rc中指定的BOOTCLASSPATH指定的classLoader。
現在看另外一個方法也就是RuntimeInit 的載入
Java代碼
- const char* envStr = getenv("CLASSPATH");
- if (envStr != NULL) {
- gDvm.classPathStr = strdup(envStr);
- } else {
- gDvm.classPathStr = strdup(".");
- }
Java代碼
- handleChildProc
Java代碼
- else {
- cloader = ClassLoader.getSystemClassLoader();
- }
-
- try {
- ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
ClassLoader.getSystemClassLoader();這個classLoader與普通的classLoader又有不同。這個是一個PathClassLoader 這個以BootClassLoader作為父Loader。這很明顯是一個裝飾者模式。