安卓开发面试题(8/30)消息机制全解析(下)
牛客高级系列专栏:
安卓(安卓系统开发也要掌握)
- 想通关安卓面试,请看(承诺免费售后答疑):《150道安卓高频面试题目录及答案链接》
- 想通关安卓系统面试,请看:《140道安卓系统Framework面试题目录及答案链接》
- 想进阶安卓开发,请看(承诺免费售后答疑):《Android进阶知识体系解析_15大安卓进阶必备知识点》
- 想了解安卓APP完整开发流程,请看(承诺免费售后答疑):《安卓APP完整开发流程》
- 想掌握安卓App性能优化,请看(承诺免费售后答疑):《安卓性能优化讲解和实战专栏》
- 想掌握Gradle语法和配置,制作Gradle插件,请看(承诺免费售后答疑):《安卓Gradle语法解析和实践大全》
嵌入式
- 想通关嵌入式面试,请看: 《111道嵌入式面试题目录及答案链接》
- 想多掌握几个嵌入式项目,请看:《6个嵌入式项目交流分享(附源码)》
本人是2020年毕业于广东工业大学研究生:许乔丹,有国内大厂CVTE和世界500强企业安卓开发经验,该专栏整理本人对常见安卓高频开发面试题的理解;
网上安卓资料千千万,笔者将继续维护专栏,一杯奶茶价格不止提供答案解析,承诺提供专栏内容免费技术答疑,直接咨询即可。助您提高安卓面试准备效率,为您面试保驾护航!
正文开始⬇
3、一问一答:常见问题汇总
经过上面的学习,到了最激动人心的时刻了,揭秘下Handler常见的问题都如何回答。一开始觉得不知道如何回答的问题,你现在一定能轻松理解
3.1 Handler 引起的内存泄露原因以及最佳解决方案
因为Handler一般是作为Activity的内部类,可以发送延迟执行的消息,如果在延迟阶段,我们把Activity关掉,此时因为该Activity还被Handler这个内部类所持有,导致Activity无法被回收,没有真正退出并释放相关资源,因此就造成内存泄漏。
工程上常用的方法是将 Handler 定义成静态的内部类,在内部持有 Activity 的弱引用,并在Acitivity的onDestroy()中调用handler.removeCallbacksAndMessages(null)及时移除所有消息。如果和面试官说了这两个方法,那你就100分过关了,但更进一步是建议将Handler抽离出来作为BaseHandler,然后每个Activity需要用到Handler的时候,就去继承BaseHandler。最佳解决方案具体代码:
// 这个是BaseHandler
public abstract class BaseHandler<T> extends Handler {
private final WeakReference<T> mWeakReference; //弱引用
protected BaseHandler(T t) {
mWeakReference = new WeakReference<T>(t);
}
protected abstract void handleMessage(T t, Message msg);
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (mWeakReference == null) {
return;
}
T t = mWeakReference.get();
if (t != null) {
handleMessage(t, msg);
}
}
}
//然后在某个Activity中使用
private static class H extends BaseHandler<XuruiActivity> { //静态的内部类哦
public H(XuruiActivity activity) {
super(activity);
}
@Override
protected void handleMessage(XuruiActivity activity, Message msg) {
//do something
}
}
//同时Activity的onDestroy函数取消掉所有消息
@Override
protected void onDestroy() {
mMyHandler.removeCallbacksAndMessages(null);
super.onDestroy();
}
3.2 为什么我们能在主线程直接使用 Handler,而不需要创建 Looper ?
详情对应2.1小节,ActivityThread是主线程操作的管理者,在 ActivityThread.main() 方法中调用了 Looper.prepareMainLooper() ,该方法调用prepare()创建Looper。因此主线程不是不需要创建Looper,而是系统帮我们做了。
3.3 Handler、Thread和HandlerThread的差别
又是这种考区别的题目,不过还算是比较常见的三个知识点:
-
Handler:本文所学的知识,是Android的一种异步消息机制,负责发送和处理消息,可实现子线程和主线程的消息通讯;
-
Thread:Java的一个多线程类,是Java进程中最小执行运算单位,用于给子类继承,创建线程/
-
HandlerThread:从名字看就知道是由前面两者结合起来的。可以理解为“一个继承自Thread的Handler类”,因此本质上和父类一样是Thread,但其内部直接实现了Looper,我们可以直接在HandlerThread里面直接使用Handler消息机制。减少了手动调用Looper.prepare()和Looper.loop()这些方法。
3.4 子线程中怎么使用 Handler?
这个题目就可以结合上面两个题目来拓展理解了。子线程中使用 Handler 需要先执行两个操作:Looper.prepare() 和 Looper.loop(),看到这里你应该要记得这两个函数执行顺序是不能变的哦。同时可以直接使用HandlerThread类即可。
3.5 为什么在子线程中创建 Handler 会抛异常?
不能在还没有调用 Looper
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
#提供免费售后答疑!!花一杯奶茶的钱获得安卓面试答疑服务,稳赚不赔# Android发展已经很多年,安卓资料网上千千万,本专栏免费提供专栏内容技术答疑!!私聊当天必回。在阅读过程或者其他安卓学习过程有疑问,都非常欢迎私聊交流。