Android热修复基础篇(二),IDEA太强悍了

System.out.println("mainClassLoader -> " + mainClassLoader);

System.out.println("appCompatClassLoader -> " + appCompatClassLoader);

System.out.println("activityClassLoader -> " + activityClassLoader);

I/System.out: mainClassLoader -> dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/com.wust.jingdutiao-jnlJr4sTotwg6ttws9yYFw==/base.apk”],nativeLibraryDirectories=[/data/app/com.wust.jingdutiao-jnlJr4sTotwg6ttws9yYFw==/lib/arm64, /system/lib64, /product/lib64]]]

appCompatClassLoader -> dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/com.wust.jingdutiao-jnlJr4sTotwg6ttws9yYFw==/base.apk”],nativeLibraryDirectories=[/data/app/com.wust.jingdutiao-jnlJr4sTotwg6ttws9yYFw==/lib/arm64, /system/lib64, /product/lib64]]]

I/System.out: activityClassLoader -> java.lang.BootClassLoader@9e062e4

运行结果分析:

  • BootClassLoader 类加载器是加载 Android 系统自带的 类,如 Activity

  • PathClassLoader 类加载器是加载 第三方类或自己写的类,(不是Android自带的),如 MainActivity、AppCompatActivity

补充点:现在你应该明白了,为什么你写的类直接调用就好了,这是因为 系统帮你选择好了 类加载器 自动帮你把需要的类加载进来,即类加载过程代码如下(系统自动替你完成了):

getClassLoader().loadClass() //在这里只是表明类加载逻辑,实际加载过程没这么简单

  • PathClassLoader源码分析

源码展示

public class PathClassLoader extends BaseDexClassLoader {

public PathClassLoader(String dexPath, ClassLoader parent) {

super((String)null, (File)null, (String)null, (ClassLoader)null);

throw new RuntimeException(“Stub!”);

}

public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {

super((String)null, (File)null, (String)null, (ClassLoader)null);

throw new RuntimeException(“Stub!”);

}

}

源码分析

  • 源码里面只包含两个构造方法

  • 构造方法中 ClassLoader parent 传的是 BootClassLoader

由于 PathClassLoader 源码太简单,没有找到我们想要的 loadClass() 方法,所以我们来看看其父类 BaseDexClassLoader,发现还是没有,继续找父类 ClassLoader,在这里面我们看到了loadClass()

//发现了两个 是重载方法

public Class<?> loadClass(String name) throws ClassNotFoundException {

//可以看到 最后还是调到了 含两个参数的 loadClass 方法,

return loadClass(name, false);

}

protected Class<?> loadClass(String name, boolean resolve)

throws ClassNotFoundException

{

// First, check if the class has already been loaded

//找缓存

//1、在Android中 class 存在于 dex file 中

//2、public PathClassLoader(String dexPath, ClassLoader parent) 第一个参数就是就是 dex 文件的存放路径

//3、所以 classLoader 在加载类的时候 是通过 IO 操作将文件读进来 ,然后按照 dex 格式解析出每一个类!

//4、为了避免你重复用一个类的时候反复 IO读取+解析 所以,先找缓存

Class<?> c = findLoadedClass(name);

//如果没找到 缓存 则进入 if语句

if (c == null) {

try {

if (parent != null) {

//1、前面我就告诉过大家 parent =》 BootClassLoader

//2、也就是说 先在 BootClassLoader 里找类

c = parent.loadClass(name, false);

} else {

//如果你的 parent==null 系统调用findBootstrapClassOrNull方法查找,看方法名字就知

c = findBootstrapClassOrNull(name);

}

} catch (ClassNotFoundException e) {

// ClassNotFoundException thrown if class not found

// from the non-null parent class loader

}

if (c == null) {

// If still not found, then invoke findClass in order

// to find the class.

//如果还是没找到 那就只能自己找了

c = findClass(name);

}

}

return c;

}

源码分析 注释已经写得很清楚了,在这里面就涉及到传说中的 双亲委托机制

为什么要用这种 双亲委托机制 ?

定义:某个类加载器在加载类时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成委托加载任务,就成功返回;只有父类加载器无法完成加载任务或者没有父类加载器时,才自己去加载。

使用原因:

  • 避免重复加载,当父类加载器已经加载了该类的时候,就没必要子ClassLoader在加载一次。

举例:加载 MainActivity 时肯定 得加载其父类  Activity,而 Activity 是由 父加载器 BootClassLoader 加载了,那你不用 双亲委托机制 ,非得 PathClassLoader 自己去加载,那不是重复了吗!!!

  • 安全性考虑,防止核心API库被随意篡改。

举例:String类 我们都知道是系统自带的 是由 BootClassLoader 加载,而你不用 双亲委托机制 ,非得用 PathClassLoader 加载,那不是加载到你写的 String类了,这样很不安全!!!

双亲委托机制 是我们本段内容的一个小插曲,我们回归主题,看一下 PathClassLoader 的 findClass() ,(PathClassLoader 源码很简单,当然没有我们想要的,所以我们得看其直接父类的(BaseDexClassLoader)实现)

public class BaseDexClassLoader extends ClassLoader {

/什么是DexPathList呢?解释如下:/

/**

  • A pair of lists of entries, associated with a {@code ClassLoader}.

  • One of the lists is a dex/resource path — typically referred

  • to as a “class path” — list, and the other names directories

  • containing native code libraries. Class path entries may be any of:

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

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

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

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

要如何成为Android架构师?

搭建自己的知识框架,全面提升自己的技术体系,并且往底层源码方向深入钻研。
大多数技术人喜欢用思维脑图来构建自己的知识体系,一目了然。这里给大家分享一份大厂主流的Android架构师技术体系,可以用来搭建自己的知识框架,或者查漏补缺;

对应这份技术大纲,我也整理了一套Android高级架构师完整系列的视频教程,主要针对3-5年Android开发经验以上,需要往高级架构师层次学习提升的同学,在这里点击GitHub免费分享,希望能帮你突破瓶颈,跳槽进大厂;

最后我必须强调几点:

1.搭建知识框架可不是说你整理好要学习的知识顺序,然后看一遍理解了能复制粘贴就够了,大多都是需要你自己读懂源码和原理,能自己手写出来的。
2.学习的时候你一定要多看多练几遍,把知识才吃透,还要记笔记,这些很重要! 最后你达到什么水平取决你消化了多少知识
3.最终你的知识框架应该是一个完善的,兼顾广度和深度的技术体系。然后经过多次项目实战积累经验,你才能达到高级架构师的层次。

你只需要按照在这个大的框架去填充自己,年薪40W一定不是终点,技术无止境

**,希望能帮你突破瓶颈,跳槽进大厂;

最后我必须强调几点:

1.搭建知识框架可不是说你整理好要学习的知识顺序,然后看一遍理解了能复制粘贴就够了,大多都是需要你自己读懂源码和原理,能自己手写出来的。
2.学习的时候你一定要多看多练几遍,把知识才吃透,还要记笔记,这些很重要! 最后你达到什么水平取决你消化了多少知识
3.最终你的知识框架应该是一个完善的,兼顾广度和深度的技术体系。然后经过多次项目实战积累经验,你才能达到高级架构师的层次。

你只需要按照在这个大的框架去填充自己,年薪40W一定不是终点,技术无止境

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值