Android的ClassLoader——实现热修复

2020-06-19  本文已影响0人  果果_Zhen

ClassLoader 就是用来加载 class 文件的,不管是 jar 中还是 dex 中的 class。

Java的ClassLoader通过双亲委派来加载各自指定路径下的 class 文件。所谓双亲委派模式就是,当类加载器收到加载类或资源的请求时,通常都是先委托给父类加载器加载,也就是说,只有当父类加载器找不到指定类或资源时,自身才会执行实际的类加载过程。

可以自定义 ClassLoader,由于双亲委派模式,因此一般覆盖 findClass() 方法,不建议重写 loadClass 方法。可查看源码。

Android 中常用的两种 ClassLoader 分别为:PathClassLoader 和 DexClassLoader。

1、PathClassLoader:用来加载系统 apk 和被安装到手机中的 apk 内的 dex 文件。

2、DexClassLoader:对比 PathClassLoader 只能加载已经安装应用的 dex 或 apk 文件,DexClassLoader 则没有此限制,可以从 SD 卡上加载包含 class.dex 的 .jar 和 .apk 文件,这也是插件化和热修复的基础,在不需要安装应用的情况下,完成需要使用的 dex 的加载。

DexClassLoader 的源码里面只有一个构造方法,代码如下:

public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent)

参数说明:

dexPath:包含 class.dex 的 apk、jar 文件路径 ,多个路径用文件分隔符(默认是“:”)分隔。

optimizedDirectory:用来缓存优化的 dex 文件的路径,即从 apk 或 jar 文件中提取出来的 dex 文件。该路径不可以为空,且应该是应用私有的,有读写权限的路

热修复

1、定义公共接口(interface)

2、热修复jar包,通过 dx 工具(sdk/build-tools)将生成的jar 包中的 class 文件优化为 dex 文件。

dx --dex --output=xxx-output.jar xxx.jar

3、加载到手机中,一般通过下载等方式,测试可直接使用adb push命令

adb push xxx-output.jar 手机中的位置

3、使用DexClassLoader加载(kotlin代码)

val dexClassLoader = DexClassLoader(jarFile.absolutePath, externalCacheDir.absolutePath, null, classLoader)//实例化DexClassLoader

try {

//加载热修复后的class,该class还需要强制转换成定义的公共接口

    val clazz = dexClassLoader.loadClass("xxx.xxx.xxx.classname").newInstance()

}catch (e:Exception) {

    e.printStackTrace()

}

注意,需要给存储权限

上一篇下一篇

猜你喜欢

热点阅读