概述 不管是Java虚拟机,还是Android中的Dalvik/ART虚拟机,都是使用ClassLoader来将Class加载到内存。...BootClassLoader是一个单例类,并且其访问修饰符是默认的,只有在同一个包中才可以访问,因此在应用程序中是无法直接使用的。...classPath, int targetSdkVersion) { String libraryPath = System.getProperty("java.library.path");...(String name) { return pathList.findLibrary(name); } } 解析: 在BaseDexClassLoader的构造函数中创建了DexPathList...在BaseClassLoader中,对于类的查找和资源的查找,都是通过其中的DexPathList实例来进行的。
ClassLoader在启动Activity的时候会调用loadClass方法,我们就从这里入手: public Activity newActivity(ClassLoader cl, String...这个时候发现ClassLoader是一个抽象类,应该是子类重写了这个方法,然后通过启动StartActivity的源码可以得到: public ClassLoader getClassLoader(String...zip, int targetSdkVersion, boolean isBundled, String librarySearchPath...>,我们继续查看DexPathList里面源码 /** * List of dex/resource (class path) elements....里面,application初始化的时候将这些多个dex文件一起修复 * * @param fixDexFiles */ private void fixDexFiles
获取相关元数据 : 获取在主应用 AndroidManifest.xml 中配置的 真实 Application 全类名 , 以及版本号信息 ; 3 ....* * DEX 解密之后的目录名称 */ String app_version; /** * 在 Application 在 ActivityThread...第三阶段 : 获取封装在 DexPathList 类中的 Element[] dexElements 数组 ; 上述的 DexPathList 对象...*/ public static native void decrypt(byte[] data, String path); } 5、OpenSSL 解密相关 NDK 源码 #include...// 将 Java String 字符串转为 C char* 字符串 const char *filePath = (*env)->GetStringUTFChars(env, path, 0)
{ /** * 加载具有指定名称的类,可以选择在 * 装载。...执行以下步骤: * * 调用{@link#findLoadedClass(String)}以确定请求的 * 类已加载 * 如果类尚未加载:在 *...这 * 参数在Android参考实现中被忽略; * 未解析类。 * @ClassNotFoundException * 如果找不到该类。 */ protected Class<?...); DexPathList pathList 成员在 BaseDexClassLoader 构造函数 , 即实例化时 , public BaseDexClassLoader(String dexPath...* * @param dexPath 包含类和 * 资源,由{@code File.pathSeparator}分隔,其中 * Android上的默认值为{@code”:“} * @param
---- 上一篇文章 自定义ClassLoader和双亲委派机制 讲述了 JVM 中的类的加载机制,Android 也是类 JVM 虚拟机那么它的类加载机制是什么呢,我们来探究一下(PS:文章源码为 Android5.1...而 Java 虚拟机是加载 class 文件,也可以将一段二进制流通过 defineClass 方法生产 Class 进行加载(PS: 自定义ClassLoader和双亲委派机制 文章后面的自定义类加载器就是通过这种方式实现的...dex 在 Android 中的加载和 class 在 jvm 中的相同都是基于双亲委派模型,都是调用ClassLoader 的 loadClass 方法加载类。...= new ArrayList(); //在自己的成员变量DexPathList中寻找,找不到抛异常 Class c = pathList.findClass...失败时,将引发IOException。
,但是我们可以在类加载动态加载外部的dex文件来达到动态加载的目的。...因为类加载器是通过包名和类名(或者说类的全限定名),所以由于委派式加载机制的存在,全限定名相同的类不会在有 祖先—子孙 关系的类加载器上分别加载一次,不管这两个类的实现是否一样。...不同的类加载器加载的类一定是不同的类,即使它们的全限定名一样。如果全限定名一样,那么根据上一条,这两个类加载器一定没有 祖先-子孙 的关系。...这样来看,可以通过自定义类加载器使得相同全限定名但实现不同的类存在于同一 JVM 中,也就是说,类加载器相当于给类在包名之上又加了个命名空间。...DexPathList public DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath
,分两个步骤,一个是先设置一些不可变的属性值,二是设置一些默认的属性值,然后将这些存储在静态变量中。.../system/DexPathList.java public String findLibrary(String libraryName) { //1....首先,这个 libraryPath 值是通过 DexPathList 的构造方法传入的,而 BaseDexClassLoader 内部的 DexPathList 对象实例化的地方也是在它自己的构造方法中...int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir...它的兼容是说,允许你在 64 位的设备上运行 32 位的进程。
文章目录 前言 一、DexPathList.java#findClass 类加载函数源码分析 二、DexFile.java#loadClassBinaryName 函数源码分析 前言 上一篇博客 【Android..., 在 BaseDexClassLoader 中的 findClass 方法中 , 主要调用 DexPathList pathList 成员的 findClass 函数查找类 ; 一、DexPathList.java...这门课在原则上与我们的课相似 * {@link java.util.zip.ZipFile}。它主要由类装入器使用。 * * 注意,我们不直接打开并读取这里的DEX文件。...* * 如果类 * 找不到,因为在每个 * 在我们查看的第一个DEX文件中找不到类的时间。...* * @param name * 类名,看起来应该像“java/lang/String” * * @param装载机 * 尝试加载类的类加载器(在大多数情况下 * 方法的调用方
文章目录 前言 一、DexPathList 构造函数分析 二、DexPathList.makeDexElements 函数分析 三、Element 类分析 前言 ---- 上一篇博客 【Android...逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 类加载器构造函数分析 | DexPathList 引入 ) 中 , 分析了 DexClassLoader 构造函数的调用流程..., 在构造函数中执行的核心操作就是 在 BaseDexClassLoader 的构造函数中 初始化了 DexPathList 实例对象 ; 本篇博客中重点分析 DexPathList ; 一、DexPathList...构造函数分析 ---- 在 DexPathList 构造函数中 , 主要是调用了 makeDexElements() 方法 , 该方法返回 Element[] 数组元素 , 赋值给 private final...三、Element 类分析 ---- Element 类是 DexPathList 的内部类 , 其第一个成员变量就是 private final File file , 这个就是 dex 文件类 ;
因为PathClassLoader在Dalvik虚拟机中只能用来加载已安装apk的类,而DexClassLoader在Dalvik和ART虚拟机中都能加载未安装apk或者dex中的类,所以热修复使用DexClassLoader...> loadClass(String name, boolean resolve) throws ClassNotFoundException { // 首先,从缓存中查找类是否已经加载...= null) { // 缓存找不到类,就委托给父加载器进行加载 c = parent.loadClass(name, false...,和类的查找过程,我们可以发现最终是通过遍历 DexPathList的 dexElements数组进行类的查找加载,当找到类就返回; dexElements数组的每个元素都代表着一个dex文件,所以为了让补丁包中要替换的类抢先于有...将 patch.dex上传到七牛云的对象存储服务器上。 patch.dex在七牛对象存储服务器上的外链:http://pm3fh7vxn.bkt.clouddn.com/patch.dex ?
我打算写了一个Plugin插件,通过transfrom的方式把所有的apt生成的class向一个注册类内插入,然后在初始化的时候调用这个注册类完成注册流程。...然后在findClass使用的就是这个DexPathList对象。...在DexPathList构造的时候会根据路径。去生成了一个dex数组,相信看过热修复机制的朋友看到这些应该已经比较熟悉了。...DexFile和类加载验证 其实我在解决异常的时候,在ClassNotFoundException上面发现了另外一个Log日志的。....class文件的格式有问题的情况下,就会导致这个dex挂载失败,然后吧就会抛出一些奇奇怪怪的类找不到的问题。
String cmd = "pm install -r -d /data/data/android.apk" Runtime run = Runtime.getRuntime(); Process process...Scaling_governor 则会显示当前的管理策略,往这个上 echo 其他类型会有相应的转变。...cpuinfo_cur_freq 可以直接看到频率变化: [f1544cd9fee741c18cd05ef4a4163135~tplv-k3u1fbpfcp-zoom-1.image] 微信安装速度可以由前面CPU低频时的20s,提升到...四、安装后 应用安装后,会遇到各种各样的问题,启动失败,合规整改(这个其实在应用开发时就要完成),那么哪些问题又是可能遇到,又可以借助apk的安装流程去解决的 4.1 targetsdkversion=...实践证明该方案完全可行,有效解决了so库找不到的问题。
我们在BaseDexClassLoader中实例化DexPathList需要用到 findClass方法, 在BaseDexClassLoader的findClass中, 本质调用了DexpathList...其他的方法姑且不用关心. 1->构造函数 public DexPathList(ClassLoader definingContext, String dexPath, String libraryPath...的构造函数中已经初始化了dexElements,所以这个方法就很好理解了,只是对Element数组进行遍历,一旦找到类名与name相同的类时,就直接返回这个class,找不到则返回null。...的方法是遍历数组 , 那么热修复的原理, 就是将改好bug的dex文件放进集合的头部, 这样遍历时会首先遍历修复好的dex并找到修复好的类 ....恩 , 接下来我们要修复bug,并且将修复好的包放进sd卡里面,这样在Splash开始时就会自动遍历到dex。
由于PathClassLoader继承于 BaseDexClassLoader对象, 并且没有覆写该方法, 故调用其父类所对应的方法. 2.3.1 DexPathList初始化 [-> DexPathList.java...接下来便是从pathList中查询目标动态库. 2.3.2 DexPathList.findLibrary [-> DexPathList.java] public String findLibrary...对于类的静态代码块,编译过程会将所有的静态代码块和静态成员变量的赋值过程都收集整合到clinit方法, 即类的初始化方法.如下: public final class System { static...findLibrary位于PathClassLoader的父类BaseDexClassLoader中: [BaseDexClassLoader.java] @Override public String...: [DexPathList.java] public DexPathList(ClassLoader definingContext, String dexPath,
ClassLoader 加载自己的class文件 类加载过程如下: 过程: 加载-连接(验证-准备-解析)-初始化 加载 将类的信息(字节码)从文件中获取并载入到JVM的内存中 连接 验证...:检查读入的结构是否符合JVM规范 准备:分配一个结构来存储类的信息 解析:将类的常量池中的所有引用改变成直接引用 初始化 执行静态初始化程序,把静态变量初始化成指定的值 其中用到的三个主要机制...中,我们发现最终加载类的是由 DexPathList 来进行的,所以我们进入了 DexPathList 这个类中,我们可以发现 在初始化的时候,有一个关键方法需要我们注意 makeDexElements...而最开始调用的 DexPathList中的findClass() 反而是由Element 调用的 findClass方法,而Emement的findClass方法中实际上又是 DexFile 调用的 loadClassBinaryName...最后我们再用一张图来总结一下Android 中类加载的过程。 在了解完上面的知识之后,我们来总结一下,Android中热修复的原理?
,最后复制到 apk 安装目录下; System.load(String pathName) :参数为 so 库在磁盘中完整的路径,可以加载自定义外部 so 库文件; 使用第三方库ReLinker,有so...比如x86库服务器下发,动态加载,瘦身效果将非常可观。但是采取常规load方式,改动有点大,底层jar包,第三库不好改加载路径。...在应用启动的时,一次注入本地so路径path,待程序使用过程中so准备后安全加载。(原因后面分析,我们先看下实践) 一. 下载So文件到sdk卡 二. copy So文件到app缓存空间 三....我们进入Runtime类的loadLibrary0()方法看看。...directory : getLibPaths()) { // getLibPaths()代码在最下方 String candidate = directory + filename;
ClassLoader 加载自己的class文件 类加载过程如下: 过程:加载-连接(验证-准备-解析)-初始化 加载 将类的信息(字节码)从文件中获取并载入到JVM的内存中 连接 验证:检查读入的结构是否符合...JVM规范 准备:分配一个结构来存储类的信息 解析:将类的常量池中的所有引用改变成直接引用 初始化 执行静态初始化程序,把静态变量初始化成指定的值 其中用到的三个主要机制: 双亲委托机制 全盘负责机制...中,我们发现最终加载类的是由 DexPathList 来进行的,所以我们进入了 DexPathList 这个类中,我们可以发现 在初始化的时候,有一个关键方法需要我们注意 makeDexElements...而最开始调用的 DexPathList中的findClass() 反而是由Element 调用的 findClass方法,而Emement的findClass方法中实际上又是 DexFile 调用的 loadClassBinaryName...最后我们再用一张图来总结一下Android 中类加载的过程。 ? 在了解完上面的知识之后,我们来总结一下,Android中热修复的原理?
不管是一个还是多个,都会一一对应一个Element,按顺序排成一个有序的数组dexElements,当找类的时候,会按顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找类则返回,如果找不到从下一个...return "fix bug class"; } } 在新建一个LoadBugClass类 public class LoadBugClass { public String...依然在该路径下执行以下命令: dx --dex --output=path_dex.jar path.jar ? 5、我们把path_dex文件拷贝到assets目录下 ?...DexPathList类系统源码如下: ?...BugClass在path_dex.jar中 结果发生了错误。
3、系统类加载器 SystemClassLoader 它负责加载系统类路径java -classpath或-D java.class.path 指定路径下的类库,也就是我们经常用到的classpath...parent:父加载器 DexClassLoader PathClassLoader DexPathList BaseDexClassLoader 总体来说,DexPathList的构造函数是将一个个的程序文件...DexPathList的findClass()方法很简单,就只是对Element数组进行遍历,一旦找到类名与name相同的类时,就直接返回这个class,找不到则返回null。...的分析,我们知道,安卓的类加载器在加载一个类时会先从自身DexPathList对象中的Element数组中获取(Element[] dexElements)到对应的类,之后再加载。...找到错误的类之后,将错误的类打包程dex文件,将其放在dexElements中的最前方。
apk 安装目录下; System.load(String pathName) :参数为 so 库在磁盘中完整的路径,可以加载自定义外部 so 库文件; 使用第三方库ReLinker,有so加载成功、...比如x86库服务器下发,动态加载,瘦身效果将非常可观。但是采取常规load方式,改动有点大,底层jar包,第三库不好改加载路径。...在应用启动的时,一次注入本地so路径path,待程序使用过程中so准备后安全加载。(原因后面分析,我们先看下实践) 一. 下载So文件到sdk卡 二. copy So文件到app缓存空间 三....我们进入Runtime类的loadLibrary0()方法看看。...directory : getLibPaths()) { // getLibPaths()代码在最下方 String candidate = directory + filename;
领取专属 10元无门槛券
手把手带您无忧上云