从源码分析 Android dexClassLoader 加载机制原理


  DexClassLoader 是加载包含classes.dex文件的jar文件或者apk文件;   通过构造函数发现需要一个应用私有的,可写的目录去缓存优化的classes。可以用使用File dexoutputDir = context.getDir(“dex”,0);创建一个这样的目录,不要使用外部缓存,以保护你的应用被代码注入。

其源码如下:

public classDexClassLoaderextendsBaseDexClassLoader {

37    /**
38     * Creates a {
   @code DexClassLoader} that finds interpreted and native
39     * code.  Interpreted classes are found in a set of DEX files contained
40     * in Jar or APK files.
41     *
42     * <p>The path lists are separated using the character specified by the
43     * {
   @code path.separator} system property, which defaults to {
   @code :}.
44     *
45     * @param dexPath the list of jar/apk files containing classes and
46     *     resources, delimited by {
   @code File.pathSeparator}, which
47     *     defaults to {
   @code ":"} on Android
48     * @param optimizedDirectory directory where optimized dex files
49     *     should be written; must not be {
   @code null}
50     * @param libraryPath the list of directories containing native
51     *     libraries, delimited by {
   @code File.pathSeparator}; may be
52     *     {
   @code null}
53     * @param parent the parent class loader
54     */
55    public DexClassLoader(String dexPath, String optimizedDirectory,
56            String libraryPath, ClassLoader parent) {
57        super(dexPath, new File(optimizedDirectory), libraryPath, parent);
58    }
59}
60

再解释下几个构造函数参数的意义:

dexpath为jar或apk文件目录。

optimizedDirectory为优化dex缓存目录。

libraryPath包含native lib的目录路径。

parent父类加载器。

然后执行的是父类的构造函数:

super(dexPath, new File(optimizedDirectory), libraryPath, parent);

BaseDexClassLoader 的构造函数如下:

public BaseDexClassLoader(String dexPath, File optimizedDirectory,String libraryPath, ClassLoader parent) {
    super(parent);
    this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
}

第一句调用的还是父类的构造函数,也就是ClassLoader的构造函数:

protected ClassLoader(ClassLoader parentLoader) {
        this(parentLoader, false);
    }
    /*
     * constructor for the BootClassLoader which needs parent to be null.
     */
    ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
       if (parentLoader == null && !nullAllowed) {
            throw new NullPointerException(“parentLoader == null && !nullAllowed”);
      }
      parent = parentLoader;
}

该构造函数把传进来的父类加载器赋给了私有变量parent。

再来看第二句:

this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
pathList为该类的私有成员变量,类型为DexPathList,进入到DexPathList函数:


/**
78     * Constructs an instance.
79     *
80     * @param definingContext the context in which any as-yet unresolved
81     * classes should be defined
82     * @param dexPath list of dex/resource path elements, separated by
83     * {
   @code File.pathSeparator}
84     * @param libraryPath list of native library directory path elements,
85     * separated by {
   @code File.pathSeparator}
86     * @param optimizedDirectory directory where optimized {
   @code .dex} files
87     * should be found and written to, or {
   @code null} to use the default
88     * system directory for same
89     */
90    public DexPathList(ClassLoader definingContext, String dexPath,
91            String libraryPath, File optimizedDirectory) {
92
93        if (definingContext == null) {
94            throw new NullPointerException("definingContext == null");
95        }
96
97        if (dexPath == null) {
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我心飞翔.坚定不移

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值