总结
【Android 详细知识点思维脑图(技能树)】
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
运行结果分析:
-
BootClassLoader 类加载器是加载 Android 系统自带的 类,如 Activity
-
PathClassLoader 类加载器是加载 第三方类或自己写的类,(不是Android自带的),如 MainActivity、AppCompatActivity
补充点:现在你应该明白了,为什么你写的类直接调用就好了,这是因为 系统帮你选择好了 类加载器 自动帮你把需要的类加载进来,即类加载过程代码如下(系统自动替你完成了):
getClassLoader().loadClass() //在这里只是表明类加载逻辑,实际加载过程没这么简单
- PathClassLoader源码分析
源码展示
public class PathClassLoader extends BaseDexClassLoader {
public PathClassLoader(String dexPath, ClassLoader parent) {
super((String)null, (File)null, (String)null, (ClassLoader)null);
throw new RuntimeException(“Stub!”);
}
public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
super((String)null, (File)null, (String)null, (ClassLoader)null);
throw new RuntimeException(“Stub!”);
}
}
源码分析
-
源码里面只包含两个构造方法
-
构造方法中 ClassLoader parent 传的是 BootClassLoader
由于 PathClassLoader 源码太简单,没有找到我们想要的 loadClass() 方法,所以我们来看看其父类 BaseDexClassLoader,发现还是没有,继续找父类 ClassLoader,在这里面我们看到了loadClass()
//发现了两个 是重载方法
public Class<?> loadClass(String name) throws ClassNotFoundException {
//可以看到 最后还是调到了 含两个参数的 loadClass 方法,
return loadClass(name, false);
}
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
//找缓存
//1、在Android中 class 存在于 dex file 中
//2、public PathClassLoader(String dexPath, ClassLoader parent) 第一个参数就是就是 dex 文件的存放路径
//3、所以 classLoader 在加载类的时候 是通过 IO 操作将文件读进来 ,然后按照 dex 格式解析出每一个类!
//4、为了避免你重复用一个类的时候反复 IO读取+解析 所以,先找缓存
Class<?> c = findLoadedClass(name);
//如果没找到 缓存 则进入 if语句
if (c == null) {
try {
if (parent != null) {
//1、前面我就告诉过大家 parent =》 BootClassLoader
//2、也就是说 先在 BootClassLoader 里找类
c = parent.loadClass(name, false);
} else {
//如果你的 parent==null 系统调用findBootstrapClassOrNull方法查找,看方法名字就知
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
//如果还是没找到 那就只能自己找了
c = findClass(name);
}
}
return c;
}
源码分析 注释已经写得很清楚了,在这里面就涉及到传说中的 双亲委托机制
为什么要用这种 双亲委托机制 ?
定义:某个类加载器在加载类时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成委托加载任务,就成功返回;只有父类加载器无法完成加载任务或者没有父类加载器时,才自己去加载。
使用原因:
- 避免重复加载,当父类加载器已经加载了该类的时候,就没必要子ClassLoader在加载一次。
举例:加载 MainActivity 时肯定 得加载其父类 Activity,而 Activity 是由 父加载器 BootClassLoader 加载了,那你不用 双亲委托机制 ,非得 PathClassLoader 自己去加载,那不是重复了吗!!!
- 安全性考虑,防止核心API库被随意篡改。
举例:String类 我们都知道是系统自带的 是由 BootClassLoader 加载,而你不用 双亲委托机制 ,非得用 PathClassLoader 加载,那不是加载到你写的 String类了,这样很不安全!!!
双亲委托机制 是我们本段内容的一个小插曲,我们回归主题,看一下 PathClassLoader 的 findClass() ,(PathClassLoader 源码很简单,当然没有我们想要的,所以我们得看其直接父类的(BaseDexClassLoader)实现)
public class BaseDexClassLoader extends ClassLoader {
/什么是DexPathList呢?解释如下:/
/**
-
A pair of lists of entries, associated with a {@code ClassLoader}.
-
One of the lists is a dex/resource path — typically referred
-
to as a “class path” — list, and the other names directories
-
containing native code libraries. Class path entries may be any of:
-
a {@code .jar} or {@code .zip} file containing an optional
-
top-level {@code classes.dex} file as well as arbitrary resources,
-
or a plain {@code .dex} file (with no possibility of associated
-
resources).
-
This class also contains methods to use these lists look up
-
classes and resources.
*/
/*这是关联一个ClassLoder 的条目列表,这其中有dex/resource path
通常称为“class path” ,其他名称目录包含本地代码库,class path条目
可能是包含一个可选的顶级class.dex的zip文件,jar文件,以及任意资源
*/
private final DexPathList pathList;
/*重写了ClassLoder的这个方法,这个方法会在loadClass中调用,当loadClass时,具体步骤是这样的:
先查找已经加载的类,如果有返回,如果没有,用父装载器去加载这个类,如果失败,则会调用我们重写的findclass这个方法*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
List suppressedExceptions = new ArrayList();
Class c = pathList.findClass(name, suppressedExceptions);
if (c == null) {
ClassNotFoundException cnfe = new ClassNotFoundException("Didn’t find class “” + name + “” on path: " + pathList);
for (Throwable t : suppressedExceptions) {
cnfe.addSuppressed(t);
}
throw cnfe;
}
return c;
}
}
最后
总而言之,Android开发行业变化太快,作为技术人员就要保持终生学习的态度,让学习力成为核心竞争力,所谓“活到老学到老”只有不断的学习,不断的提升自己,才能跟紧行业的步伐,才能不被时代所淘汰。
在这里我分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
602972)]
还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!