什么是类加载器?
类加载器(class loader)是 Java™中的一个很重要的概念。类加载器负责加载 Java 类的字节代码到 Java 虚拟机中。
Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。
Dalvik虚拟机类加载机制
Dalvik的虚拟机不能用ClassCload直接加载.dex,Android从ClassLoader派生出了两个类:DexClassLoader和PathClassLoader;而这两个类就是我们加载dex文件的关键,这两者的区别是:
这里(参考)[https://segmentfault.com/a/1190000004062880]讲得很详细
生成外部dex文件
|
|
这两者只是简单的对BaseDexClassLoader做了一下封装
平时进行动态加载开发的时候,使用DexClassLoader就够了。但我们也可以创建自己的类去继承ClassLoader,需要注意的是loadClass方法并不是final类型的,所以我们可以重载loadClass方法并改写类的加载逻辑。
动态加载进来的class如何使用,一般有2种办法
一种是使用反射调用,这种我不多做介绍。
一种是使用接口编程的方式来调用对应的方法,毕竟.dex文件也是我们自己维护的,所以可以把方法抽象成公共接口,把这些接口也复制到主项目里面去,就可以通过这些接口调用动态加载得到的实例的方法了。
源码包下面新建一个包名称是dynamic,然后在dynamic下新建一个interface接口Dynamic,里面有个接口方法,就叫DynamicXor(String st)吧,返回一个String,到时候我们可以通过Toast弹出来,Dynamic.java:
接着在dynamic目录下新建一个imp包,创建Impdynamic.java,并实现Dynamic接口:
点击Build -> make project,这时候会在build\intermediates\classes\debug目录下生成对应的classes文件。
好了我们要把DynamicImpl这个class转换成Dalvik可识别的dex文件,分两步:
打包jar
打开app目录下的build.gradle文件最后,加上以下代码
打开AS的 terminal窗口:
执行成功,出现Build Successfully,会在生成app/build/libs/dynamic.jar
jar转成dex
使用sdk提供dx.jar将导出的dynamic.jar转换成Dalvik可识别的dex格式,sdk已经将dx.jar放到build-tools\27.0.3\lib目录下,将dynamic.jar复制到dx.jar目录下,AS终端运行
在dx.jar目录下会生成一个dynamic_dex.jar文件(Davilk虚拟机可执行的dex文件,因为这条命令同时会打包dex文件,因此后缀是jar),接下来就是要在demo中使用这个dex文件。
主程序
新建一个项目,在app/src/main/新建一个assets目录,把刚刚生成的dynamic_dex.jar文件放到assets目录下
FileUtils.java
新建一个FileUtils.java,FileUtils类是从assets目录下copy文件到app/data/cache目录
FileUtils
main.java
main函数
其他
activity_main.xml配置如下:
strings配置如下:
check1.java
申请权限
AndroidManifest中申请权限,