Android解析ClassLoader(二)Android中的ClassLoader

269 阅读4分钟
转载自blog.csdn.net/itachi85/ar…

Android中的ClassLoader类型和Java中的ClassLoader类型类似,也分为两种类型,分别是系统ClassLoader和自定义ClassLoader。其中系统ClassLoader主要有3种分别是BootClassLoader、PathClassLoader和DexClassLoader。 

 1.1 BootClassLoader 

Android系统启动时会使用BootClassLoader来预加载常用类,与Java中的BootClassLoader不同,它并不是由C/C++代码实现,而是由Java实现的

class BootClassLoader extends ClassLoader {

    private static BootClassLoader instance;

    @FindBugsSuppressWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")
    public static synchronized BootClassLoader getInstance() {
        if (instance == null) {
            instance = new BootClassLoader();
        }

        return instance;
    }
}

BootClassLoader是ClassLoader的内部类,并继承自ClassLoader。BootClassLoader是一个单例类,需要注意的是BootClassLoader的访问修饰符是默认的,只有在同一个包中才可以访问,因此我们在应用程序中是无法直接调用的。

1.2 DexClassLoader 

DexClassLoader可以加载dex文件以及包含dex的压缩文件(apk和jar文件),不管是加载哪种文件,最终都是要加载dex文件,为了方便理解和叙述,将dex文件以及包含dex的压缩文件统称为dex相关文件。 来查看DexClassLoader的代码,如下所示。 

public class DexClassLoader extends BaseDexClassLoader {
55      public DexClassLoader(String dexPath, String optimizedDirectory,
56              String librarySearchPath, ClassLoader parent) {
57          super(dexPath, new File(optimizedDirectory), librarySearchPath, parent);
58      }
59  }
60  

DexClassLoader的构造方法有四个参数: dexPath:dex相关文件路径集合,多个路径用文件分隔符分隔,默认文件分隔符为‘:’ optimizedDirectory:解压的dex文件存储路径,这个路径必须是一个内部存储路径,一般情况下使用当前应用程序的私有路径:/data/data/<Package Name>/...。 librarySearchPath:包含 C/C++ 库的路径集合,多个路径用文件分隔符分隔分割,可以为null。 parent:父加载器。 DexClassLoader 继承自BaseDexClassLoader ,方法实现都在BaseDexClassLoader中。

1.3 PathClassLoader

 Android系统使用PathClassLoader来加载系统类和应用程序的类,来查看它的代码:

public class PathClassLoader extends BaseDexClassLoader {
26      /**
27       * Creates a {@code PathClassLoader} that operates on a given list of files
28       * and directories. This method is equivalent to calling
29       * {@link #PathClassLoader(String, String, ClassLoader)} with a
30       * {@code null} value for the second argument (see description there).
31       *
32       * @param dexPath the list of jar/apk files containing classes and
33       * resources, delimited by {@code File.pathSeparator}, which
34       * defaults to {@code ":"} on Android
35       * @param parent the parent class loader
36       */
37      public PathClassLoader(String dexPath, ClassLoader parent) {
38          super(dexPath, null, null, parent);
39      }
40  
41      /**
42       * Creates a {@code PathClassLoader} that operates on two given
43       * lists of files and directories. The entries of the first list
44       * should be one of the following:
45       *
46       * <ul>
47       * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as
48       * well as arbitrary resources.
49       * <li>Raw ".dex" files (not inside a zip file).
50       * </ul>
51       *
52       * The entries of the second list should be directories containing
53       * native library files.
54       *
55       * @param dexPath the list of jar/apk files containing classes and
56       * resources, delimited by {@code File.pathSeparator}, which
57       * defaults to {@code ":"} on Android
58       * @param librarySearchPath the list of directories containing native
59       * libraries, delimited by {@code File.pathSeparator}; may be
60       * {@code null}
61       * @param parent the parent class loader
62       */
63      public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
64          super(dexPath, null, librarySearchPath, parent);
65      } 

PathClassLoader继承自BaseDexClassLoader,实现也都在BaseDexClassLoader中。 PathClassLoader的构造方法中没有参数optimizedDirectory,这是因为PathClassLoader已经默认了参数optimizedDirectory的值为:/data/dalvik-cache,很显然PathClassLoader无法定义解压的dex文件存储路径,因此PathClassLoader通常用来加载已经安装的apk的dex文件(安装的apk的dex文件会存储在/data/dalvik-cache中)。 

Android ClassLoader的继承关系

VnM5ZT.png

  1. ClassLoader是一个抽象类,其中定义了ClassLoader的主要功能。BootClassLoader是它的内部类。 
  2. SecureClassLoader类和JDK8中的SecureClassLoader类的代码是一样的,它继承了抽象类ClassLoader。SecureClassLoader并不是ClassLoader的实现类,而是拓展了ClassLoader类加入了权限方面的功能,加强了ClassLoader的安全性。
  3.  URLClassLoader类和JDK8中的URLClassLoader类的代码是一样的,它继承自SecureClassLoader,用来通过URl路径从jar文件和文件夹中加载类和资源
  4. InMemoryDexClassLoader是Android8.0新增的类加载器,继承自BaseDexClassLoader,用于加载内存中的dex文件。 
  5. BaseDexClassLoader继承自ClassLoader,是抽象类ClassLoader的具体实现类PathClassLoader和DexClassLoader都继承它。

BootClassLoader和PathClassLoader的创建

BootClassLoader是在Zygote进程的入口main方法中preload(bootTimingsTraceLog)创建的,PathClassLoader则是在Zygote进程创建SystemServer进程时创建的