(一) Android ClassLoader 种类
1.BootClassLoader
主要加载 AndroidFrameWork 层的一些 class 字节码文件
2.PathClassLoader
用来加载已经安装在系统中的 apk 文件中的 class 文件
3.DexClassLoader
用来加载指定目录中的 class 字节码文件
4.BaseDexClassLoader
PathClassLoader 和 DexClassLoader 的父类文件
一个 app 应用至少要拥有 BootClassLoader 和 PathClassLoader
代码演示如下:
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 加载当前 MainActivity 使用的 ClassLoader
- ClassLoader classLoader = getClassLoader();
- if (classLoader != null) {
- Log.e("classLoader-------->", classLoader.toString());
- // 遍历父 classLoader
- while (classLoader.getParent() != null) {
- classLoader = classLoader.getParent();
- Log.e("classLoader parent---->", classLoader.toString());
- }
- }
- }
日志打印:
- classLoader-------->: dalvik.system.PathClassLoader
- classLoader parent---->: java.lang.BootClassLoader@7c8f1da
(二) Android ClassLoader 特点
1. 双亲代理模式的特点:
双亲代理模式分三个过程: classLoader 在加载字节码的时候, 首先会询问当前的 classloader 是否已经载 过子类, 如果已经加载过, 直接返回不再重复加载. 如果没有查询 parent 是否加载过子类, 如果加载过那么返回 parent 加载过的字节码文件. 如果没有加载过, 最终再由子 classloader 去完成真正的加载.
2. 特点作用
2.1 提高类加载的效率
这个过程的好处就是如果我们一个类被树中任一一个 classloader 节点加载过, 那么我们在以后的整个生命周期中都不会再被去重新的加载, 大大提高了类加载的效率.
2.2 类加载的共享功能
比如我们的 framework 层级的类, 一旦被我们顶层的 classLoader 加载过可以缓存在内存里面, 以后任何地方用到, 都不需要重新加载
2.3 类加载隔离功能
不能继承路线上的 classloader 加载的类肯定不是同一个类, 好处避免用户自己写一些代码冒充核心的类库, 来访问我们类库中可见的成员变量, 举例: 一些系统层级的类会在初始化的时候就被加载, 如 java.lang.string 在应用启动之前就被系统加载好的, 如果在一个应用里面能够简单的用自己定义的 string 类把系统的替换掉, 那就存在很大的安全问题.----> 如何判断两个类是同一个类: 相同的包名 + 相同的类名 + 同一个 classloader 去加载三个条件必须同时具备.
(三) 源码解析
...
来源: http://www.jianshu.com/p/4b5a6a78efff