源码阅读:类加载器 BaseDexClassLoader

Android 和 Java中的类加载机制都是双亲委派模型

但是Android和Java中实现的类加载器的是不同的

Android中用到的是DexClassLoader()

 

类加载器的构造方法

 public BaseDexClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, ClassLoader[] sharedLibraryLoaders,
            ClassLoader[] sharedLibraryLoadersAfter,
            boolean isTrusted)

类加载器的构造方法如上,

parent:是父加载器

sharedLibraryLoader 一部分系统共享的库,暂时不确定这部分是怎样确定的

sharedLibraryLoaderAfter 另一部分系统共享的库

在加载类的吧遍历顺序

1. shareLibraryLoader

2. dexPathList

3. sharedLibraryLoadersAfter

 

双亲委派机制中的具体代码

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    c = findClass(name);

                    // Android-removed: Android has no jvmstat.
                    // this is the defining class loader; record the stats
                    // PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    // PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    // PerfCounter.getFindClasses().increment();
                }
            }
            return c;
    }

加载类的顺序

1. 先让parent类加载器尝试加载

2. 让BootstrapClassLoader尝试加载

3.当前类加载器尝试加载

 

具体的实现时使用 findClass 去加载具体的类

 

BaseDexClassLoader

在Android中,使用PathClassLoader和DexClassLoader进行类的加载,这两个类都是BaseDexClassLoader的基类

 @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // First, check whether the class is present in our shared libraries.
        if (sharedLibraryLoaders != null) {
            for (ClassLoader loader : sharedLibraryLoaders) {
                try {
                    return loader.loadClass(name);
                } catch (ClassNotFoundException ignored) {
                }
            }
        }
        // Check whether the class in question is present in the dexPath that
        // this classloader operates on.
        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
        Class c = pathList.findClass(name, suppressedExceptions);
        if (c != null) {
            return c;
        }
        // Now, check whether the class is present in the "after" shared libraries.
        if (sharedLibraryLoadersAfter != null) {
            for (ClassLoader loader : sharedLibraryLoadersAfter) {
                try {
                    return loader.loadClass(name);
                } catch (ClassNotFoundException ignored) {
                }
            }
        }
        if (c == null) {
            ClassNotFoundException cnfe = new ClassNotFoundException(
                    "Didn't find class \"" + name + "\" on path: " + pathList);
            for (Throwable t : suppressedExceptions) {
                cnfe.addSuppressed(t);
            }
            throw cnfe;
        }
        return c;
    }

 

posted on 2025-12-31 18:32  落子无悔96  阅读(3)  评论(0)    收藏  举报

导航