本系列文章专注分享大型Bat面试知识,后续会持续更新,喜欢的话麻烦点击一个关注
面试官: 系统如何加载一个dex文件,他的底层原理是怎么实现的
心理分析:面试官想知道你是否有过对dex加载相关经验。此题主要为tinker热修复做铺垫。dex加载与热修复是有关系的,求职者一定要注意 面试官后续会面试到tinker
**求职者:**应该从DexClassLoader 加载出发
DexClassLoader 是加载包含classes.dex文件的jar文件或者apk文件; 通过构造函数发现需要一个应用私有的,可写的目录去缓存优化的classes。可以用使用File dexoutputDir = context.getDir(“dex”,0);创建一个这样的目录,不要使用外部缓存,以保护你的应用被代码注入。
其源码如下:
public classDexClassLoaderextendsBaseDexClassLoader {
public DexClassLoader(String dexPath, String optimizedDirectory,
String libraryPath, ClassLoader parent) {
super(dexPath, new File(optimizedDirectory), libraryPath, parent);
}
}
再解释下几个构造函数参数的意义:
-
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);
}
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函数:
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) {
98 throw new NullPointerException("dexPath == null");
99 }
100
101 if (optimizedDirectory != null) {
102 if (!optimizedDirectory.exists()) {
103