Android 类加载器特性说明

Android 类加载器特性说明

前言

学习插件,要先了解上一篇Android动态加载器。因为这篇文章已经说到了类加载器的一个特性,隔离:类加载器可以实现隔离(即各个模块独立)。所以,类加载器是实现插件化一个很重要的基础。那可能会有人问,既然各个模块独立了,怎么实现多个模块的数据访问呢?其实,上篇文章Android动态加载器也说到了加载器的共享特性,利用这个特性,数据访问也就清晰了。那么,通过举例来说明下这个2个特性。

数据隔离特性

因为每个加载器,有自己的独立的类名称空间。JVM 及 Dalvik 对类唯一的识别是 ClassLoader id + PackageName + ClassName,即ClassLoader如果不同,两个类必定不等。
那么来看如下有3个类A、B、C:

package com.test;
public class A {
    int age = 10;
}
package com.test;
public class B {
    int age = 10;
}
package com.test;
public class C{
    int age = 10;
}

假设用2个Loader来分别加载,如图所示:
图一

因为loader2、loader3是不同的加载器,对象不同,此时虚拟机会认为类A,是2个不同的类;故会被加载2份(每个加载器都会加载一份)。
而B和C,本身类名不同,会分别加载一份。这样来说,如果2个加载器有数据等相互访问,就不能达到效果,所以我们要利用共享来达到目的。

类加载共享

类加载共享父类已经加载过的类。过程是先看自己是否已经加载过,已经加载,就使用本加载器加载的类;否则会递归查找父类是否有加载,未加载则会抛出异常: ClassNotFoundException
这里说的父类,非java定义的继承关系的类。而是指类加载器对象之间的关系。类加载器可能是同一个加载器的对象,如MyClassLoader类,有2个对象Loader1、Loader2;Loader2中包装了一个父类加载器Loader1,那么Loader1和Loader2之间就是父子关系。Loader1是Loader2的父类加载器。那么来还是如上说的3个类。
假设,用3个加载器来加载这几个类:
其中,loader1是Loader2、Loader3的Parent。
图二
伪代码如下:

//伪代码
Class<?> classB1 = classLoader1.loadClass("com.test.B”);
Class<?> classC1 = classLoader1.loadClass("com.test.C”);

Class<?> classA2 = classLoader2.loadClass("com.test.A”);
Class<?> classB2 = classLoader2.loadClass("com.test.B”);

Class<?> classA3 = classLoader3.loadClass("com.test.A”);
Class<?> classC3 = classLoader3.loadClass("com.test.C”);

那么,虚拟机运行时候加载的B、C类分别就是这样的:
Class B:仅加载一份,由父类Loader1加载
Class C:仅加载一份,由父类Loader1加载
父子关系中,同一个类仅被加载一份,说明子加载器加载的类对象可以访问父加载器中的对象;这样数据是共享的。这个共享特性就可以让Loader2、Loader3将数据共享到父类loader1中,再通过Loader1,获取各自需要的数据。

总结

通过以上说明,了解了动态类加载的隔离和共享特性。因为这个特性,在庞大的应用开发中,可以利用这2个特性,做到功能模块的隔离,同时也能做到模块间数据的共享。
一般就是采用以上图二的策略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值