今天来彻底了解一下这个android的这个jar和dex,主要参考下方连接文章。
一、基本概念
1.1 首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar
原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行。这一点在咱们Android项目打包的apk中可以看出:引入其他Jar的内容都被打包进了classes.dex。
所以这条路不通,请大家注意。
1.2 当前哪些API可用于动态加载
1.2.1 DexClassLoader
这个可以加载jar/apk/dex,可以从SD卡中加载,也可以通过其静态方法loadDex(path, outpath, 0) 得到DexFile对象。
1.2.2 PathClassLoader
通过构造函数new DexFile(path)来产生DexFile对象。只能加载已经安装到Android系统中的apk文件。
这两者的区别在于DexClassLoader需要提供一个可写的outpath路径,用来释放.apk包或者.jar包中的dex文件。也就是说PathClassLoader不能主动从zip包中释放出dex,因此只支持直接操作dex格式文件,或者已经安装的apk(因为已经安装的apk在cache中存在缓存的dex文件), 而DexClassLoader可以支持.apk、.jar和.dex文件,并且会在指定的outpath路径释放出dex文件。
加载好类后,通常我们可以通过Java反射机制来使用这个类但是这样效率相对不高,而且也比较复杂凌乱。更好的做法是定义一个interface,并将这个interface写进容器端。待加载的类,继承自这个interface,并且有一个参数为空的构造函数,以使我们能够通过Class的newInstance方法产生对象然后将对象强制转换为interface对象,就可以直接调用成员方法了。
当你的jar中包含或者使用了第三方的类库你也可以定个规范的interface,并在你要加载的jar中实现这个interface,我们称这个实现为proxy类,通过proxy类调用你引用的第三方jar。我们将这个规范interface单独打成jar包放在主工程里,原理同上。