个人笔记-2022安卓面试整理

162 阅读2分钟

下周有个面试,迫不得已只能逼着自己去复习以前的知识点了,好多都忘了,平时太懒,临时抱佛脚或许还有点用吧。

其实不是特别知道从哪里开始比较好,毕竟面试的东西那么多,每个面试官都不一样。

想了想,因为自己项目中有热更新的相关内容就从热更新开始吧

很好

在此之前贴上借鉴 的博客

blog.csdn.net/czZ\_\_czZ/…

juejin.cn/post/695650…

那么什么是ClassLoader: 

类加载(ClassLoader) , java 源码文件编译后会生成一个 class 文件,而在 Android 中,将代码编译后会生成一个 apk 文件,将 apk 文件解压后就可以看到其中有一个或多个 classes.dex 文件,它就是安卓把所有 class 文件进行合并,优化后生成的。

 ClassLoader 是一个抽象类,实现类主要分为两种类型:系统类加载器和自定义加载器。 

其中系统类加载器主要包括三种: PathClassLoader --- 用于 Android 应用程序类加载器。可以加载指定的 dex ,以及 jar 、 zip 、 apk 中的 classes.dex,三方的sdk 

BootClassLoader ---用于 加载 Android Framework 层 class 文件。自带的sdk DexClassLoader ---用于加载制定的dex,以及jar、zip、apk中的classes.dex

 pathclassloader和dexclassloader

 // libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
 public class PathClassLoader extends BaseDexClassLoader {
 // optimizedDirectory 直接为 null 
    public PathClassLoader(String dexPath, ClassLoader parent) { 
        super(dexPath, null, null, parent); 
    }
  // optimizedDirectory 直接为 null
    public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        super(dexPath, null, librarySearchPath, parent);
    }
}
 

// API 小于等于 26/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java public class DexClassLoader extends BaseDexClassLoader {
    public DexClassLoader(String dexPath, String optimizedDirectory,
                          String librarySearchPath, ClassLoader parent) {
        // 26开始,super里面改变了,看下面两个构造方法
        super(dexPath, new File(optimizedDirectory), librarySearchPath, parent);
    }
}
 
// API 26/libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
 public BaseDexClassLoader(String dexPath, File optimizedDirectory, String librarySearchPath, ClassLoader parent) {
    super(parent);
    // DexPathList 的第四个参数是 optimizedDirectory,可以看到这儿为 null
    this.pathList = new DexPathList(this, dexPath, librarySearchPath, null); }
 
    // API 25/libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java public             
    BaseDexClassLoader(String dexPath, File optimizedDirectory, String librarySearchPath, ClassLoader parent) {
    super(parent);
    this.pathList = new DexPathList(this, dexPath, librarySearchPath, optimizedDirectory); }

根据源码了解到,PathClassLoader 和 DexClassLoader 都是继承自 BaseDexClassLoader,且类中只有构造方 法,它们的类加载逻辑完全写在 BaseDexClassLoader 中。 其中我们值的注意的是,在8.0之前,它们二者的唯一区别是第二个参数 optimizedDirectory,这个参数的意思是 生成的 odex(优化的dex)存放的路径,PathClassLoader 直接为null,而 DexClassLoader 是使用用户传进来的 路径,而在8.0之后,二者就完全一样了。 下面我们再来了解下 BootClassLoader 和 PathClassLoader 之间的关系。

// 在 onCreate 中执行下面代码 
ClassLoader classLoader = getClassLoader(); 
while (classLoader != null) {
    Log.e("leo", "classLoader:" + classLoader);
    classLoader = classLoader.getParent();
}
Log.e("leo", "classLoader:" + Activity.class.getClassLoader());

classLoader:dalvik.system.PathClassLoader[DexPathList[[zip file 
"/data/user/0/com.enjoy.pluginactivity/cache/plugin-debug.apk", zip file 
"/data/app/com.enjoy.pluginactivity-T4YwTh-
8gHWWDDS19IkHRg==/base.apk"],nativeLibraryDirectories=[/data/app/com.enjoy.pluginactivity-T4YwTh-8gHWWDDS19IkHRg==/lib/x86_64, /system/lib64, /vendor/lib64]]] 
classLoader:java.lang.BootClassLoader@a26e88d 
classLoader:java.lang.BootClassLoader@a26e88d

 通过打印结果可知,应用程序类是由 PathClassLoader 加载的,Activity 类是 BootClassLoader 加载的,并且 BootClassLoader 是 PathClassLoader 的 parent,这里要注意 parent 与父类的区别。这个打印结果我们下面还 会提到。