android进阶篇01、Android类加载机制与Dex文件简介,这份火爆全网的452页Android Framework内核解析

return null;

}

4、在这个方法中,会去循环遍历dexElements,然后调用Element的findClass方法;那么这个dexElements是啥呢?在DexPathList构造方法中对其进行了赋值:

public DexPathList(ClassLoader definingContext, String dexPath,

String librarySearchPath, File optimizedDirectory) {

// save dexPath for BaseDexClassLoader

this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,

suppressedExceptions, definingContext);

}

5、splitDexPath --> splitPaths ,会返回一个List;

private static List splitPaths(String searchPath, boolean directoriesOnly) {

List result = new ArrayList<>();

if (searchPath != null) {

for (String path : searchPath.split(File.pathSeparator)) {

if (directoriesOnly) {

try {

StructStat sb = Libcore.os.stat(path);

if (!S_ISDIR(sb.st_mode)) {

continue;

}

} catch (ErrnoException ignored) {

continue;

}

}

result.add(new File(path));

}

}

return result;

}

6、makeDexElements方法会返回一个Element数组,可以看到在此方法中通过File构建DexFile,然后通过DexFile构建Element,最后将Elements数组返回:

private static Element[] makeDexElements(List files, File optimizedDirectory,

List suppressedExceptions, ClassLoader loader) {

Element[] elements = new Element[files.size()];

int elementsPos = 0;

/*

  • Open all files and load the (direct or contained) dex files up front.

*/

for (File file : files) {

if (file.isDirectory()) {

// We support directories for looking up resources. Looking up resources in

// directories is useful for running libcore tests.

elements[elementsPos++] = new Element(file);

} else if (file.isFile()) {

String name = file.getName();

if (name.endsWith(DEX_SUFFIX)) {

// Raw dex file (not inside a zip/jar).

try {

DexFile dex = loadDexFile(file, optimizedDirectory, loader, elements);

if (dex != null) {

elements[elementsPos++] = new Element(dex, null);

}

} catch (IOException suppressed) {

System.logE("Unable to load dex file: " + file, suppressed);

suppressedExceptions.add(suppressed);

}

} else {

DexFile dex = null;

try {

dex = loadDexFile(file, optimizedDirectory, loader, elements);

} catch (IOException suppressed) {

/*

  • IOException might get thrown “legitimately” by the DexFile constructor if

  • the zip file turns out to be resource-only (that is, no classes.dex file

  • in it).

  • Let dex == null and hang on to the exception to add to the tea-leaves for

  • when findClass returns null.

*/

suppressedExceptions.add(suppressed);

}

if (dex == null) {

elements[elementsPos++] = new Element(file);

} else {

elements[elementsPos++] = new Element(dex, file);

}

}

} else {

System.logW("ClassLoader referenced unknown path: " + file);

}

}

if (elementsPos != elements.length) {

elements = Arrays.copyOf(elements, elementsPos);

}

return elements;

}

7、现在我们知道了dexElements是啥了,我们回到步骤3,调用了Element的findClass

public Class<?> findClass(String name, ClassLoader definingContext,

List suppressed) {

return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)
null;

}

8、然后调用DexFile的loadClassBinaryName方法:

public Class loadClassBinaryName(String name, ClassLoader loader, List suppressed) {

return defineClass(name, loader, mCookie, this, suppressed);

}

9、接着会调用defineClass:

private static Class defineClass(String name, ClassLoader loader, Object cookie,

DexFile dexFile, List suppressed) {

Class result = null;

try {

result = defineClassNative(name, loader, cookie, dexFile);

} catch (NoClassDefFoundError e) {

if (suppressed != null) {

suppressed.add(e);

}

} catch (ClassNotFoundException e) {

if (suppressed != null) {

suppressed.add(e);

}

}

return result;

}

10、最后调用到Native方法defineClassNative:

private static native Class defineClassNative(String name, ClassLoader loader, Object cookie,

DexFile dexFile) throws ClassNotFoundException, NoClassDefFoundError;

四、热修复思路策略

通过上面类加载机制的分析可知,Elements数组中存储的Element元素,Element元素又是通过DexFile构建的,DexFile只是对dex文件的一个封装而已;因此我们可以总结一种热修复的思路:

设计模式学习笔记

设计模式系列学习视频

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-SDZShVht-1710963886574)]
[外链图片转存中…(img-Muqrte9I-1710963886575)]
[外链图片转存中…(img-J4NdyP7a-1710963886575)]
[外链图片转存中…(img-RSrDAS05-1710963886576)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-JmdBpwrQ-1710963886576)]

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值