[安卓开发日记] ClassLoader
2020-04-10 本文已影响0人
chopperhl
一、安卓中的三种ClassLoader
DexClassLoader、PathClassLoader、BootClassLoader(DexClassLoader和PathClassLoader在8.0以后完全一样,8.0之前会多一个odex目录的构造参数)
二、双亲委托机制。
loadClass方法调用时会从当前的ClassLoader一层一层向上查找这个类是否被加载,如果被加载直接返回已经加载的class,如果没有则调用父亲的loadClass继续判断是否已经加载,直到到达顶层的ClassLoader,顶层的loader如果发现没有加载,就会自己加载class,如果加载成功就返回,不成功则回溯到儿子loader加载,直到最后成功加载或者加载失败。
这种机制可以防止class被重复加载,也能防止篡改核心类。
三、插件化和热修复原理
通过Context.getClassLoader获取到apk宿主程序的PathClassLoader(继承自BaseDexClassLoader),然后通过反射获取DexPathList pathList的Field,DexPathList对象的dexElements主要保存从apk加载Dex信息。
通过 PathClassLoader(String dexPath, ClassLoader parent) 构造插件的ClassLoader然后利用反射获取dexElements数组,最后拼接设置回宿主的ClassLoader中,即实现了插件化和热修复的动态类加载。
public class BaseDexClassLoader extends ClassLoader {
@UnsupportedAppUsage
private final DexPathList pathList;
}
public final class DexPathList {
/**
* List of dex/resource (class path) elements.
* Should be called pathElements, but the Facebook app uses reflection
* to modify 'dexElements' (http://b/7726934).
*/
@UnsupportedAppUsage
private Element[] dexElements;
}