【建议收藏】Android 中高级大厂面试源码秘籍,面试题 + 笔记 + 项目实战
如果你没有阅读过源码,面试官可能会对回答的结果不满意,进而导致面试结果不太理想,但如果你对源码有所研究,并能够很好地问答面试官的问题,这可能就是你的加分点,可以形成自己独特的竞争力,吊打面试官,升职加薪不是梦。
Android 开发常见源码面试题
1.Glide :加载、缓存、LRU 算法 (如何自己设计一个大图加载框架) (LRUCache 原理)2.EventBus3.LeakCanary4.ARouter5.插件化(不同插件化机制原理与流派,优缺点。局限性)6.热修复 7.RXJava (RxJava 的线程切换原理)8.Retrofit (Retrofit 在 OkHttp 上做了哪些封装?动态代理和静态代理的区别,是怎么实现的)9.OkHttp...
(二)解决问题(bug)
IllegalArgumentException 分析
java.lang.IllegalArgumentException: You cannot start a load for a destroyed activityat com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:102)at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:87)at com.bumptech.glide.Glide.with(Glide.java:629)at com.r......utils.glide.GlideHelper.loadImage(GlideHelper.java:229)at com.r......DetailActivity.init(.....DetailActivity.java:423)............at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:887)
这个是在使用 Glide 的时候遇到的一个问题。这里如果单纯的找到日志中出现的我们写的类,并不能很好的找到解决思路。像这类问题呢,其实有个重要的方法那
就是追本溯源,什么意思呢。别看着错误 log 日志一大堆,这段日志第一行大意是非法参数异常,不能为一个销毁的 activity 加载数据。第一行只是告诉我们错误大致意思,其实也知道了错误原因了。但是从第二行才可以找到问题的根源了。代码是:at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)。这段代码可以从 Glide 源码中找出。找到这个 RequestManagerRetriever 类的 assertNotDestroyed()方法。源码如下:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)private static void assertNotDestroyed(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {throw new IllegalArgumentException("You cannot start a load for a destroyed activity");}}
这里我们可以看出 You cannot start a load for a destroyed activity 这句话就是从这里向 IllegalArgumentException()中作为参数传入,并且抛出了这个异常。在看这段代码,有个判断,一个是版本号大于 J,并且 activity.isDestroyed()都为真时,才抛出这个异常。版本号现在基本都是大于 J 了,而当我们 activity 销毁后,Glide 还在工作,这时就抛出了这个异常了。相当于我主线程都销毁了,你 Glide 特么还工作个毛线?加载个数据谁要?因此程序不干了,给你报错吧。这里说明 Glide 写的真心不错的。这里抛出的这个异常信息还是非常明确的。下面来看看怎么处理:
if (Util.isOnMainThread()){Glide.with(getApplicationContext()).load(url).into(view);}......@Overrideprotected void onDestroy() {super.onDestroy();if (Util.isOnMainThread()){
Glide.with(this).pauseRequest();}}
在 onDestory()中加入了判断,如果 Activity 销毁的话,那么 Glide 停止工作啦。老板都走了你加班给谁看呢???从这个例子可以看出,log 日志中除了我们自己写的类注意观察一下外,前两行日志还是非常重要的。
(三)提升编程能力读一本好书,就是和许多高尚的人谈话。-歌德
和阅读一本好书一样,阅读源码就是和编程大牛面对面交流的机会,在许多优秀的开源项目中,它们的编码规范和架构设计都是很棒的,另外在设计上也使用了大量的设计模式,通过阅读和学习源码,能够快速提升我们的编码水平,以及对设计模式有更深的理解。
同时,在我们阅读完一个源码后,可以触类旁通,能够快速地对其他框架的源码进行阅读和学习,减少时间成本。
除了上述提到的原因之外,可能还有许多,在这里就不一一赘述了,那么在确定了要阅读源码之后,就让我们看下如何阅读源码吧!
如何阅读源码?
1.深入解析微信 MMKV 源码[MMKV](
)?是微信于 2018 年 9 月 20 日开源的一个 K-V 存储库,它与 SharedPreferences 相似,但又在更高的效率下解决了其不支持跨进程读写等弊端。
2.深入解析阿里巴巴路由框架 ARouter 源码组件化被越来越多的 Android 项目采用,而作为组件化的基础——路由也是重中之重。因此详细的分析阿里巴巴开源的路由框架 ARouter。从源码的角度解释为什么这样使用,以及避免做什么,让你使用地更加顺滑。
3.深入解析 AsyncTask 源码(一款 Android 内置的异步任务执行库)AsyncTask?是 Android SDK 中提供的一个用于执行异步任务的框架,在 Android 兴起的早期被广泛使用,但如今已经被 RxJava、协程等新兴框架所取代。虽然它存在着一些不足,但我们还是可以尝试了解一下它的实现原理以及存在的不足。
4.深入解析 Volley 源码(一款 Google 推出的网络请求框架)Volley 是 Google 开发的一款网络请求框架,目前已停止更新。虽然目前大家的关注焦点都在 Retrofit、OkHttp 等第三方网络请求框架,团队的项目中所用的也是这两个框架,但 Volley 中还是有非常多优秀的设计思想值得我们去学习的。
5.深入解析 Retrofit 源码在 Andrroid 开发中,网络请求十分常用,而在 Android 网络请求库中,Retrofit 是当下最热的一个网络请求库。
6.深入解析 OkHttp 源码 OkHttp 是一个处理网络请求的开源项目,是 Android 端最火热的轻量级框架,由移动支付 Square 公司贡献用于替代 HttpUrlConnection 和 Apache HttpClient。随着 OkHttp 的不断成熟,越来越多的 Android 开发者使用 OkHttp 作为网络框架。
7.深入解析[](
)ButterKnife 源码作为 Android 开发者,大家肯定都知道大名鼎鼎的 butterknife。它大大的提高了开发效率,虽然在很早之前大家就开始使用它了,但是只知道是通过注解的方式实现的,却一直没有仔细的学习下大牛的代码。所以有必要系统的分析下 butterknife 的实现原理。
8.深入解析 Okio 源码(一套简洁高效的 I/O 库)Okio 中有两个非常重要的接口——Sink?以及?Source,它们都继承了?Closeable,其中?Sink?对应了我们原来所使用的?OutputStream,而?Source?则对应了我们原来所使用的?InputStream。
评论