「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
1.ClassLoader的类型
Android中的ClassLoader类型和Java中的ClassLoader类型类似,也分为两种类型,分别是系统ClassLoader和自定义ClassLoader。其中系统ClassLoader主要有3种分别是BootClassLoader、PathClassLoader和DexClassLoader。
1.1 BootClassLoader
Android系统启动时会使用BootClassLoader来预加载常用类,与Java中的BootClassLoader不同,它并不是使用C/C++代码实现,而是由Java实现的,BootClassLoader代码如下:
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;
}
public BootClassLoader() {
super(null);
}
...
}
BootClassLoader是ClassLoader的内部类,并继承自ClassLoader。BootClassLoader是一个单例类,需要注意的是BootClassLoader的访问修饰符是默认的,只有在同一个包中才可以访问,因此我们在应用程序中无法直接调用。
1.2 PathClassLoader
Android系统使用PathClassLoader来加载系统类和应用程序的类,代码如下:
public class PathClassLoader extends BaseDexClassLoader {
public PathClassLoader(String dexPath, ClassLoader parent) {
super((String)null, (File)null, (String)null, (ClassLoader)null);
throw new RuntimeException("Stub!");
}
public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
super((String)null, (File)null, (String)null, (ClassLoader)null);
throw new RuntimeException("Stub!");
}
}
PathClassLoader继承自BaseDexClassLoader,实现也都在BaseDexClassLoader中。
1.3 DexClassLoader
DexClassLoader可以加载dex文件以及包含dex的压缩文件(apk和jar文件),代码如下:
public class DexClassLoader extends BaseDexClassLoader {
public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) {
super((String)null, (File)null, (String)null, (ClassLoader)null);
throw new RuntimeException("Stub!");
}
}
构造方法的4个参数:
- dexPath:dex相关文件的路径,多个使用冒号分隔
- optimizedDirectory:解压的dex文件存储路径,路径必须为内部存储路径,一般使用程序私有路径:/data/data/{package_name}/
- librarySearchPath:包含c/c++库的路径集合,多个路径用分隔符分隔,可为null
- parent:父加载器
DexClassLoader继承自BaseDexClassLoader,方法都在BaseDexClassLoader中。
2.ClassLoader的继承关系
可以看到上面一共有8个ClassLoader相关类,其中有一些和Java中的ClassLoader相关类十分类似,下面简单对它们进行介绍:
- ClassLoader是一个抽象类,其中定义了ClassLoader的主要功能。BootClassLoader是它的内部类。
- SecureClassLoader类和JDK8中的SecureClassLoader类的代码是一样的,它继承了抽象类ClassLoader。SecureClassLoader并不是ClassLoader的实现类,而是拓展了ClassLoader类加入了权限方面的功能,加强了ClassLoader的安全性。
- URLClassLoader类和JDK8中的URLClassLoader类的代码是一样的,它继承自SecureClassLoader,用来通过URl路径从jar文件和文件夹中加载类和资源。
- InMemoryDexClassLoader是Android8.0新增的类加载器,继承自BaseDexClassLoader,用于加载内存中的dex文件。
- BaseDexClassLoader继承自ClassLoader,是抽象类ClassLoader的具体实现类,PathClassLoader和DexClassLoader都继承它。