DexClassLoader和PathClassLoader网上好多错的说法,我们聊一下

一、错误说法

看到网上说如下错误说法:
一般说起 PathClassLoader 和 DexClassLoader ,大家都会说,前者只能加载内存中已经安装的apk中的dex,而后者可以加载sd卡中的apk/jar。
大家心中的回答一定是 PathClassLoader 是用来加载已经安装的 apk 的,DexClassLoader 是用来加载存储空间的 dex / apk 文件的。为什么这样说呢,因为之前我也一直这样理解的,而且网上大部分文章中也都是这样讲解的。

以前我看书,看文章也会先给自己一种暗示,认为书上是对的,博客是对的,后来发现错误还真不少。比如wait()需要抛出异常,点进去一看源码就有,网上很多说不用。言归正传,本篇说一下网上对PathClassLoader和DexClassLoader的错误说法和源码分析。

二、正确说法

先说正确的,
1、PathClassLoader和DexClassLoader在8.0(API26)之前,唯一的区别就是第二个参数optimizedDirectory,这个参数的意思是生成的odex(优化的dex)存放的路径。在8.0及之后,二者完全一样。
2、PathClassLoader 和 DexClassLoader 都能加载外部的 dex/apk,只不过区别是 DexClassLoader 可以指定 optimizedDirectory,也就是 dex2oat 的产物 .odex 存放的位置,而 PathClassLoader 只能使用系统默认位置。但是这个 optimizedDirectory 在 Android 8.0 以后也被舍弃了,只能使用系统默认的位置了。

三、源码探究

通过Android社区看源码,http://androidos.net.cn/sourcecode
看一下8.0的DexClassLoader:

public class DexClassLoader extends BaseDexClassLoader {
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String librarySearchPath, ClassLoader parent) {
        super(dexPath, null, librarySearchPath, parent);
    }
}

可以看到确实是继承了BaseDexClassLoader,DexClassLoader只有一个构造方法,四个参数。第一个参数是dexPath,也就是dex文件的路径;第二个参数是优化路径,就是dex文件在加载之前会先优化成odex文件,odex文件的位置由第二个参数决定;第三个参数是so文件路径;第四个参数是new DexClassLoader的时候传进去的。

看一下8.0的PathClassLoader:

public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super(dexPath, null, null, parent);
    }
    public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        super(dexPath, null, librarySearchPath, parent);
    }
}

PathClassLoader两个构造方法,两个构造方法只有第三个参数so文件路径的区别,我们看第二个构造方法就行了。看得出PathClassLoader和DexClassLoader唯一区别是第二个参数。我们看这个区别继续,看他们的父类BaseDexClassLoader的源码

8.0的BaseDexClassLoader源码:

  /**
 * @param optimizedDirectory this parameter is deprecated and has no effect since API level 26.
 */
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
        String librarySearchPath, ClassLoader parent) {
    this(dexPath, optimizedDirectory, librarySearchPath, parent, false);
}

   public BaseDexClassLoader(String dexPath, File optimizedDirectory,
        String librarySearchPath, ClassLoader parent, boolean isTrusted) {
    super(parent);
    this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);

    if (reporter != null) {
        reportClassLoaderChain();
    }
}

找到四个参数对应的构造方法,可以看到第二个参数optimizedDirectory根本没有用到,而且批注也说了弃用optimizedDirectory.

所以得出结论,8.0及以后,DexClassLoader和PathClassLoader是没有区别的。

附:
https://blog.csdn.net/valada/article/details/100189694

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值