Android源码探究之BaseDexClassLoader的使用

目录
  • 前言
  • 一.dexPath(String)
  • 二.optimizedDirectory
  • 三.librarySearchPath
  • 四.parent
  • 五.总结

前言

一共有4个参数,分来来讲。

1:dexFile(String类型)
2:optimizedDirectory(File类型)
3:librarySearchPath(String类型)
4:parent(ClassLoader类型)

一.dexPath(String)

官方的注释:

     * @param dexPath the list of jar/apk files containing classes and
     * resources, delimited by {@code File.pathSeparator}, which
     * defaults to {@code ":"} on Android.

包含类和类的jar/apk文件列表资源,由{@code File.pathSeparator}分隔,其中Android上的默认值为{@code”:“}。

也就是说这里其实是可以传入一个集合的。

比如如下的参数都是可以被接受的:

sdcard/test/aa.apk

sdcard/test/aa.apk:sdcard/test/bb.apk:sdcard/test/cc.apk

sdcard/test/aa.apk:sdcard/test/dd.jar

其中分隔符:,保险起见,可以使用File.pathSeparator替代。

示例代码如下:

private void loadDex(List<File> apkList) {
        StringBuilder builder = new StringBuilder();
        for (File f : apkList) {
            builder.append(f.getAbsolutePath());
            builder.append(File.separatorChar);
        }
        DexClassLoader dexClassLoader = new DexClassLoader(builder.toString(), null, null, getClass().getClassLoader());
    }

二.optimizedDirectory

官方的注释:

this parameter is deprecated and has no effect since API level 26.

解压的路径,这里传入路径的最主要目的就是为了生成odex文件夹,方便后续存储odex文件。

如注释中所写,这个参数26开始已经失效了。所以这里就不扩展去讲了。

三.librarySearchPath

官方的注释:

* @param librarySearchPath the list of directories containing native

包含native目录的目录列表,这里要注意的,传入的一定是so的上一级目录才可以。如果是更上一层的目录是不行的。前言中的问题就出在这,传入了一个更上一层的目录地址。

排查流程:

最终使用librarySearchPath的地方是在DexPathList的splitPaths方法中。生成File加入List中:

@UnsupportedAppUsage
    private static List<File> splitPaths(String searchPath, boolean directoriesOnly) {
        List<File> result = new ArrayList<>();
        if (searchPath != null) {
            for (String path : searchPath.split(File.pathSeparator)) {
                ...
                result.add(new File(path));
            }
        }
        return result;
    }

而使用的时候,是使用了findLibrary的方法,for循环便利上面集合中的所有path,看是否存在。

public String findLibrary(String libraryName) {
        String fileName = System.mapLibraryName(libraryName);
        for (NativeLibraryElement element : nativeLibraryPathElements) {
            String path = element.findNativeLibrary(fileName);
            if (path != null) {
                return path;
            }
        }
        return null;
    }

而寻找的最终会调用到NativeLibraryElement的findNativeLibrary方法:

public String findNativeLibrary(String name) {
            maybeInit();
            if (zipDir == null) {
                String entryPath = new File(path, name).getPath();
                if (IoUtils.canOpenReadOnly(entryPath)) {
                    return entryPath;
                }
            } else if (urlHandler != null) {
                // Having a urlHandler means the element has a zip file.
                // In this case Android supports loading the library iff
                // it is stored in the zip uncompressed.
                String entryName = zipDir + '/' + name;
                if (urlHandler.isEntryStored(entryName)) {
                  return path.getPath() + zipSeparator + entryName;
                }
            }
            return null;
        }

这段代码也就是问题的核心了,直接使用了new File(path,name)的方式,而不是循环查找,所以只有上一层才可以。

四.parent

官方的注释:

@param parent the parent class loader

这个比较简单,就是上一层的classLoader。

五.总结

无论是dexPath还是librarySearchPath,都是支持多路径传入的。路径之间使用File.pathSeparator进行分隔。dexPath中必须是APK或者Jar包的路径,而librarySearchPath中必须是so文件的上一层级文件夹才可以。

到此这篇关于Android源码探究之BaseDexClassLoader的使用的文章就介绍到这了,更多相关Android BaseDexClassLoader内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解析Android框架之Volley源码

    Volley简单使用 我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖. 好了,接下来上代码了..... //获取volley的请求对象 RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext()); StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, "http://www.baidu.com

  • Android开发Retrofit源码分析

    目录 项目结构 retrofit 使用 Retrofit #create ServiceMethod #parseAnnotations HttpServiceMethod#parseAnnotations 第二种 非Kotlin协程情况 DefaultCallAdapterFactory#get 第一种 Kotlin协程情况 总结 项目结构 把源码 clone 下来 , 可以看到 retrofit 整体结构如下 图 http包目录下就是一些http协议常用接口 , 比如 请求方法 url ,

  • Android项目开发常用工具类LightTaskUtils源码介绍

    目录 LightTaskUtils概述 LightTaskUtils截图 LightTaskUtils源码 版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl LightTaskUtils概述 LightTaskUtils是一个轻量级的线程管理工具. LightTaskUtils截图 LightTaskUtils截图如下: LightTaskUtils源码 LightTaskUtils源码如下: import android.os.Handl

  • 分析Android Choreographer源码

    一.前言 目前大部分手机都是 60Hz 的刷新率,也就是 16.6ms 刷新一次,系统为了配合屏幕的刷新频率,将 Vsync 的周期也设置为 16.6 ms,每个 16.6 ms , Vsync 信号唤醒 Choreographer 来做 App 的绘制操作,这就是引入 Choreographer 的主要作用.了解 Choreographer 还可以帮助 App 开发者知道程序每一帧运行的基本原理,也可以加深对 Message.Handler.Looper.MessageQueue.Measur

  • Android源码探究之BaseDexClassLoader的使用

    目录 前言 一.dexPath(String) 二.optimizedDirectory 三.librarySearchPath 四.parent 五.总结 前言 一共有4个参数,分来来讲. 1:dexFile(String类型)2:optimizedDirectory(File类型)3:librarySearchPath(String类型)4:parent(ClassLoader类型) 一.dexPath(String) 官方的注释: * @param dexPath the list of

  • Android源码学习之工厂方法模式应用及优势介绍

    工厂方法模式定义: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 常用的工厂方法模式结构: 如上图所示(截取自<Head Firs

  • 从Android源码剖析Intent查询匹配的实现

    前言     这篇文章主要是介绍一下Android Intent,并且从Android源码的角度对Intent查询匹配过程进行分析. Intent介绍     Intent的中文是"意图"的意思,而意图是一个非常抽象的概念,那么在Android的编码设计中,如何实例化意图呢?因此Android系统明确指定一个Intent可由两方面属性来衡量. 主要属性:包括Action和Data.其中Action用于表示该Intent所表达的动作意图,Data用于表示该Action所操作的数据.   

  • Android 源码如何编译调试

    android提供的工具链和开发工具比较完善,因此它的开发环境的搭建比较简单,相信许多朋友都已经搭建好环境,并编写了HelloActivity入门程序了.这里先看几个问题: 1.android的文件系统结构是怎样的,我们安装的程序放在那里? 编译android源码之后,在out/target/product/generic一些文件: ramdisk.img.system.img.userdata.img. system. data.root 其中, system.img是由 system打包压缩

  • Windows下获取Android 源码方法的详解

    前言:略!获取源码的原因千千万~~~ 1.安装GIT工具.GIT是林纳斯·托瓦兹大神为了管理器Linux内核开发而创立的分布式版本控制软件.下载地址:http://code.google.com/p/msysgit/一路next将安装进行到底. 2.在磁盘剩余空间较大的磁盘下新建一个文件夹,用于存放源码.我在F盘下:新建了androidsourcecode文件夹. 3.访问Android源码网站,获取你所需要的源码"下载链接".网站地址:http://android.git.kerne

  • Ubuntu Android源码以及内核下载与编译

    本教程是基于Ubuntu下Android6.0.1源码以及内核的下载和编译,记录一下,以后也就不用自己去找资料,一遍一遍的尝试了.可以翻墙的,英语好的,直接去AndroidSource. 系统环境:Ubuntu14.04LTS Android版本:6.0.1 重要网址 清华大学镜像 AndroidSource 下载前的准备 安装OpenJdk sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update sudo apt-get in

  • Android源码学习之组合模式定义及应用

    组合模式定义: Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 如上图所示(截取自<Head First De

  • Android源码学习之观察者模式应用及优点介绍

    观察者模式定义: Define a one-to-many dependency between objects so that when one object changes state, all its dependents aer notified and updated automatically. 定义对象间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新.  如上图所示(截取自<Head First Design Patterns>一书),

  • Android源码学习之单例模式应用及优点介绍

    单例模式定义: Ensure a class has only one instance, and provide a global point of access to it. 动态确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 如上图所示(截取自<Head First Design Patterns>一书). 通过使用private的构造函数确保了在一个应用中产生一个实例,并且是自行实例化(在Singleton中自己使用new Singleton()). 具体单例模式有

  • android源码探索之定制android关机界面的方法

    本文实例讲述了android源码探索之定制android关机界面的方法.分享给大家供大家参考.具体如下: 在Android系统中,长按Power键默认会弹出对话框让你选择"飞行模式","静音","关机"等功能.如下图所示: 但这些功能都对Android-x86和其他终端产品就没什么必要了.本文就简单介绍下如何定制关机界面. 我的目标是长按Power键,将会关机,弹出"设备将要关机"选择对话框.如果可以选择"是&quo

随机推荐