Android高性能高稳定性代码覆盖率方案原理解析

前言

《Android高性能高稳定性代码覆盖率方案技术实践》一文中,我们实现了高效稳定的代码覆盖率采集方案。不少同学对其背后原理非常感兴趣,甚至发私信来询问底层的理论支撑。为了方便大家了解其中原理,我们写下了这篇详细的解析文章,欢迎大家阅读探讨。

方案中使用了新建ClassLoader,复制目标ClassLoader的classTable字段并进行类加载状态查询的方式,如图:

0d4b04dc1b00d1cd3b85af5e40833771.png

为什么要采取这样的方式?下面我们来一探究竟。

从ClassLoader入手

我们都知道Android和Java的类加载机制非常相似,都是使用ClassLoader进行。在Java中,要采集类级别的代码覆盖率非常简单,直接反射调用ClassLoader的findLoadedClass方法就行,那为什么在Android中却那么困难呢?这得从Android独有的类加载优化机制说起。

我们先来看看Android类加载涉及的几个主要的ClassLoader,如下图:

outside_default.png

其中,

  • BootClassLoader负责加载系统类

  • PathClassLoader负责加载应用自定义类

  • DexClassLoader一般用于动态加载应用安装包以外的类

代码覆盖率应当关注的是应用自定义的类,所以我们重点看看PathClassLoader和DexClassLoader。

我们先来看一下ClassLoader是如何加载一个类的,核心代码都在它的loadClass方法中,如下:

//源码路径:/java/lang/ClassLoader.java 
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        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加载一个类时主要有以下三个步骤:

1.检查类是否已经加载,如果是,则直接返回加载过的类,否则进入下一步。

2.如果有parent,则尝试从parent加载(双亲委派模式);否则,从BootStrap ClassLoader中查找。如果成功找到类,则直接返回,否则进入下一步。

3.尝试自己加载类。

第一步中用来判断类是否加载的findLoadedClass方法,源码如下:

//源码路径:/java/lang/ClassLoader.java  
protected final Class<?> findLoadedClass(String name) {
    ClassLoader loader;
    if (this == BootClassLoader.getInstance())
        loade
  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值