文章目录 前言 一、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装载机 * 尝试加载类的类加载器(在大多数情况下 * 方法的调用方
环境: struts 2.3.16.3 + Convention Plugin 2.3.16.3 实现零配置 现象:以文件夹方式部署在weblogic(10.3.3)上时一切正常,换成war包部署,运行时提示找不到...检查生成的war包中\WEB-INF\classes\下有无META-INF目录,如果没有,在eclipse里resource\META-INF下随便放一个文件,比如test.xml,这样maven打包生成...war包时,才会在classes下创建META-INF目录 ?
天坑 遇到的问题:使用命令行执行命令:java EightSample,会报以下错误 错误: 找不到或无法加载主类 EightSample 运行环境 mac系统 IntelliJ IDEA编译器...问题原因 是因为idea编辑的时候加上了包名导致的错误 解决办法1 去掉第一行的package JavaProgramming; ,然后在EightSample.java文件的当前目录编译java
双亲委派:所谓的双亲委派,则是先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。...通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父加载器,依次递归,如果父加载器可以完成类加载任务,就成功返回;只有父加载器无法完成此加载任务时,才自己去加载。 缓存机制。...是在Zygote进程的入口方法中创建的,PathClassLoader则是在Zygote进程创建SystemServer进程时创建的。...的构造函数,其实DexPathList的findClass()方法很简单,就只是对Element数组进行遍历,一旦找到类名与name相同的类时,就直接返回这个class,找不到则返回null。...的分析,我们知道,安卓的类加载器在加载一个类时会先从自身DexPathList对象中的Element数组中获取(Element[] dexElements)到对应的类,之后再加载。
---- 上一篇文章 自定义ClassLoader和双亲委派机制 讲述了 JVM 中的类的加载机制,Android 也是类 JVM 虚拟机那么它的类加载机制是什么呢,我们来探究一下(PS:文章源码为 Android5.1...dex 在 Android 中的加载和 class 在 jvm 中的相同都是基于双亲委派模型,都是调用ClassLoader 的 loadClass 方法加载类。...Android 中想通过这种方式实现类的加载时不行的。...Android系统中的类加载器 Android 系统屏蔽了 ClassLoader 的 findClass 加载方法,那么它自己的类加载时通过什么样的方式实现的呢?...DexPathList中寻找,找不到抛异常 Class c = pathList.findClass(name, suppressedExceptions); if (c
则自己开始加载 // 如果自己加载不了 , 则继续委托给子节点执行加载 if (clazz == null) { clazz = findClass(className); } 实际上加载类的方法是...{ /** * 加载具有指定名称的类,可以选择在 * 装载。...这 * 参数在Android参考实现中被忽略; * 未解析类。 * @ClassNotFoundException * 如果找不到该类。 */ protected Class<?...); DexPathList pathList 成员在 BaseDexClassLoader 构造函数 , 即实例化时 , public BaseDexClassLoader(String dexPath...* * @param dexPath 包含类和 * 资源,由{@code File.pathSeparator}分隔,其中 * Android上的默认值为{@code”:“} * @param
所以libs里没有放入SO,运行时肯定找不到SO。...修复方式 添加SO:libs\armeabi\libBugly.so或加载代码注释掉://System.loadLibrary(Bugly) ; 2、进阶错误——根本木有X86的SO,在X86的设备上你加载个球啊...x86设备上系统会把apk中libs目录下x86的SO,拷贝到应用的私有目录下。...虽然libs下有armeabi的SO,但没有放入x86的SO,运行时还是找不到libbugly.so。...code if(getArch().contain(“arm”)){ //只在arm下加载 System.loadLibrary(Bugly) ; System.loadLibrary
因为双亲委托机制,所以宿主中所有类的加载都会走到 DelegateClassLoader.findClass 中,但是 DelegateClassLoader 中因为不存在宿主类,所以必然找不到,因此一个宿主类的加载会多调用了一次无用的...在 JVM 中,类第一次加载时,肯定之前是没有加载过的,因此 findLoadedClass 应该是返回 null 的,而 BootClassLoader 中只有系统类,因此宿主类的加载应该是调用了 PathClassLoader...中加载的类(app image的作用是记录已经编译好的“热代码”,并且在启动时一次性把它们加载到缓存,参考Tinker博客)。...ART 上对 class 加载做的一个优化,但是在 Dalvik 中是没有这段逻辑的,可以参考/dalvik/native/javalangVMClassLoader.cpp。...结论 在 Android ART 中默认的 ClassLoader 机制,在 ClassLoader#findLoadedClass 时就把 JVM 中的 findLoadedClass 和 findClass
我们在BaseDexClassLoader中实例化DexPathList需要用到 findClass方法, 在BaseDexClassLoader的findClass中, 本质调用了DexpathList...的构造函数中已经初始化了dexElements,所以这个方法就很好理解了,只是对Element数组进行遍历,一旦找到类名与name相同的类时,就直接返回这个class,找不到则返回null。...2.热修复的实现方法 加载class会使用BaseDexClassLoader,在加载时,会遍历文件下的element,并从element中获取dex文件 方案 ,class文件在dex里面 , 找到dex...恩 , 接下来我们要修复bug,并且将修复好的包放进sd卡里面,这样在Splash开始时就会自动遍历到dex。...因为在dex中的class文件是包名.类名的形式 , 所以我们在做dex文件时, 也要讲相对应的包名加上 . 这里反编译一个demo作为例子: ?
ClassLoader加载过,那么在以后整个系统的生命周期内,这个类永远不会被重新加载。...DexClassLoader与PathClassLoader 平时开发的时候,使用DexClassLoader就够用了,但是我们不妨挖一下这两者具体细节上的区别。...} } return null; } 这里遍历了之前所有的DexFile实例,其实也就是遍历了所有加载过的dex文件,再调用loadClassBinaryName方法一个个尝试能不能加载想要的类...** Android程序比起使用动态加载时麻烦在哪里 ** 通过上面的分析,我们知道使用ClassLoader动态加载一个外部的类是非常容易的事情,所以很容易就能实现动态加载新的可执行代码的功能,但是比起一般的...如果是运行时动态加载进来的新类,那类里面用到R.id的地方将会抛出找不到资源或者用错资源的异常,因为新类的资源ID根本和现有的Resource实例中保存的资源ID对不上;
因为PathClassLoader在Dalvik虚拟机中只能用来加载已安装apk的类,而DexClassLoader在Dalvik和ART虚拟机中都能加载未安装apk或者dex中的类,所以热修复使用DexClassLoader...来加载补丁包中的类。...= null) { // 缓存找不到类,就委托给父加载器进行加载 c = parent.loadClass(name, false...,和类的查找过程,我们可以发现最终是通过遍历 DexPathList的 dexElements数组进行类的查找加载,当找到类就返回; dexElements数组的每个元素都代表着一个dex文件,所以为了让补丁包中要替换的类抢先于有...将 patch.dex上传到七牛云的对象存储服务器上。 patch.dex在七牛对象存储服务器上的外链:http://pm3fh7vxn.bkt.clouddn.com/patch.dex ?
defineClassNative 函数 二、dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数分析 前言 上一篇博客...【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )...这大致相当于defineClass() * 在常规VM中——类装入器调用它以导致 * 创建特定类。不同之处在于,搜索和 * 字节的读取是在VM中完成的。...* * 类名是一个“二进制名称”,例如“java.lang.String”。 * * 如果找不到类,则返回空指针,无异常。 * 在其他失败时引发异常。...异常,请扼杀它,因为 * 较高方法中的contract表示,如果 * 找不到该类。
上一步中,我们已经将so文件从系统apk构建流程中删除,并且拷贝到了指定目录下。那么现在我们应该做什么呢? 将so文件打包成.zip压缩包。 生成该资源对应的实体类DynamicPkgInfo。...保证第三方sdk在缺少so文件时,不崩溃 很多三方sdk都要求在应用启动时,进行初始化,一个使用so库的类的典型类代码如下: public class ThirdLib{ //静态方法加载so库 static...so库异常时,将该库的名称保存下来,在我们的so包被正常下发加载后,再次调用本方法,将so库load到系统中。...将so包路径加入DexPathList的数组头部。 遍历等待加载so列表,尝试加载所有so文件,并将成功加载的so文件,移除该列表。 将资源id和本地路径加入缓存,防止so被重复加载。...其他方法调用到我们的SoloadUtil时,我们判断我们的加载系统是否初始化完成 已完成,则调用Relinkder库尝试加载so文件,未完成则将该so库加入待加载队列中。
, 尝试在父类中查找该字段 * 如果有父类 , 则在父类中查找 * 如果在父类中找到 , 返回该字段 *..., 尝试在父类中查找该字段 for (Class<?..., 尝试在父类中查找该字段 * 如果有父类 , 则在父类中查找 * 如果在父类中找到 , 返回该字段 *..., 尝试在父类中查找该方法 for (Class<?...// 这里要做一个判断 // 不能修改宿主应用的资源 // 只有插件包中的 Activity 才进行相应的修改 // 在调用插件包中的组件时
二、启动优化 直奔主题,常见的启动优化方式大概有这些: 闪屏页优化 MultipDex优化(本文重点) 第三方库懒加载 WebView优化 线程优化 系统调用优化 2.1 闪屏页优化 消除启动时的白屏/...需要注意的是闪屏页的Activity,包括闪屏页中引用到的其它类必须在主dex中,不然在MultiDex.install之前加载这些不在主dex中的类会报错Class Not Found。.../launchtest/SplashActivity.class 在已有项目中用这种方式,一顿操作猛如虎之后,编译运行在4.4的机器上,启动闪屏页,加载完准备进入主页直接崩掉了。...**第三方库中的ContentProvider必须指定在主dex中,否则也会找不到,为什么?...所以这种方案的缺点很明显: MultiDex加载逻辑放在闪屏页的话,闪屏页中引用到的类都要配置在主dex。
,但是我们可以在类加载动态加载外部的dex文件来达到动态加载的目的。...因为类加载器是通过包名和类名(或者说类的全限定名),所以由于委派式加载机制的存在,全限定名相同的类不会在有 祖先—子孙 关系的类加载器上分别加载一次,不管这两个类的实现是否一样。...不同的类加载器加载的类一定是不同的类,即使它们的全限定名一样。如果全限定名一样,那么根据上一条,这两个类加载器一定没有 祖先-子孙 的关系。...这样来看,可以通过自定义类加载器使得相同全限定名但实现不同的类存在于同一 JVM 中,也就是说,类加载器相当于给类在包名之上又加了个命名空间。...如果两个相同全限定名的类由两个非 祖先-子孙 关系的类加载器加载,这两个类之间通过instanceof 和 equals() 等进行比较时总是返回false。
Android中的类加载是通过DexClassLoader,在DexClassLoader中使用DexpathList将所有的dex文件加载到dexElements数组中,在进行.class加载的时候,...如上图,我们将一个修复后的Class文件HotFixTest文件打包成一个patch.dex文件,在App启动的时候,动态的将其加载到dexElements的最开始位置,这样在App加载的时候就会优先的加载这个热修复的类...Tinker会创建一个TinkerClassLoader类加载器,在这个类加载器中尝试加载class(loadClass),要是TinkerClassLoader加载不到class文件,会将加载任务提交到...Android在加载类的时候,会遍历pathList对象的dexElements数组,该数据中是apk下所有dex文件的信息,在开始加载class文件的时候,会遍历dexElements数组,查看class...在Android10上禁止了dex文件的动态加载,所以无法对基准版本和patch文件的dex进行合并优化,从而无法实现类替换的功能,Tinker针对Android10,通过反射机制PackageManagerService
DexPathList 中通过 File 生成 DexFile 的源码 , 在 makeDexElements 中调用了 loadDexFile 方法 , 在 loadDexFile 又有调用了 DexFile.loadDexFile...这门课在原则上与我们的课相似 * {@link java.util.zip.ZipFile}。它主要由类装入器使用。 * * 注意,我们不直接打开并读取这里的DEX文件。...这门课在原则上与我们的课相似 * {@link java.util.zip.ZipFile}。它主要由类装入器使用。 * * 注意,我们不直接打开并读取这里的DEX文件。...这门课在原则上与我们的课相似 * {@link java.util.zip.ZipFile}。它主要由类装入器使用。 * * 注意,我们不直接打开并读取这里的DEX文件。...在…上 * 失败时,将引发IOException。
文章目录 一、DexClassLoader 类加载器构造函数分析 二、DexPathList 引入 一、DexClassLoader 类加载器构造函数分析 ---- DexClassLoader 是加载..., 都定义在 BaseDexClassLoader.java 代码中 ; DexClassLoader 的构造函数 , 调用了 BaseDexClassLoader 的构造函数 ; public class...} } 源码路径 : /libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java 查询 ClassLoader 源码时..., 在源码路径中检索出两个 ClassLoader , 分别是 Dalvik 下的 ClassLoader : /libcore/libdvm/src/main/java/java/lang/ClassLoader.java..., 因此分析的是 /libcore/libdvm/src/main/java/java/lang/ClassLoader.java 源码 ; 在 BaseDexClassLoader 中调用的 ClassLoader
在Dalvik虚拟机中,总是在运行时通过JIT(Just-In—Time)把字节码文件编译成机器码文件再执行,这样跑起来程序就很慢,所在ART上,改为AOT(Ahead-Of—Time)提前编译,即在安装应用或...但是AOT有个缺点就是每次执行的时间都太长了,并且占用的ROM空间又很大,所以在Android N上Google做了混合编译同时支持JIT和AOT。...混合编译的作用简单来说,在应用运行时分析运行过的代码以及“热代码”,并将配置存储下来。在设备空闲与充电时,ART仅仅编译这份配置中的“热代码”。...app image中已经存在的类会被插入到ClassLoader的ClassTable,再次加载类时,直接从ClassTable中取而不会走DefineClass。...也就是说A类是在dex.loader配置中的,补丁后,A依然在oldDex1中,而A的直接引用类B却出现在了newDex1中,并且在之前A类已经被打上了preverify标志,所在A再去newDex1中加载
领取专属 10元无门槛券
手把手带您无忧上云