引言
最近在后台上看到有很多人留言,说在面试或者晋升考核中都遇到了关于 Handler、Binder 机制的难题,相信大家在金九银十这个面试季中也会遇到类似的难题;现在面试官的问题都是根据你做过的项目进行深入探讨,如若对技术原理和底层逻辑没有深入了解的话,那么你通过面试的机会会显著下降
近期也是收集并整理了关于 Android Framework 的逻辑知识点总结和 Handler、Binder 机制的学习手册,相信能够解决大家对底层逻辑,技术原理,源码解析,面试真题等等相关技术知识点得不够了解透彻的问题,下面为大家展示一下 Handler、Binder 机制的相关面试真题实例
面试真题实例
Handler 被设计出来的原因?有什么用?
一种东西被设计出来肯定就有它存在的意义,而 Handler 的意义就是切换线程
作为 Android 消息机制的主要成员,它管理着所有与界面有关的消息事件,常见的使用场景有:
- 跨进程之后的界面消息处理
- 比如 Activity 的启动,就是 AMS 在进行进程间通信的时候,通过 Binder 线程将消息发送 ApplicationThread 的消息处理者 Handler,然后再将消息分发给主线程中去执行
- 网络交互后切换到主线程进行 UI 更新
- 当子线程网络操作之后,需要切换到主线程进行 UI 更新
总之一句话,Hanlder 的存在就是为了解决在子线程中无法访问 UI 的问题
Handler 线程是如何切换的?
- 假设现在有一个线程 A,在 A 线程中通过 Looper.prepare 和 Looper.loop 来开启 Looper,并且在A线程中实例化出来一个 Handler
- Looper.prepare() 方法被调用时会为会初始化 Looper 并为 ThreadLocal 设置 Looper,此时 ThreadLocal 中就存储了 A 线程的 Looper;另外 MessageQueue 也会在 Looper 中被初始化
- 接着当调用 Loop.loop 方法时,loop 方法会通过 myLooper 得到A线程中的 Looper,进而拿到 Looper 中的 MessageQueue,接着开启死循环等待执行 MessageQueue 中的方法
- 此时,再开启一个线程 B,并在 B 线程中通过 Handler 发送出一个 Message,这个 Message 最终会通过 sendMessageAtTime 方法调用到 MessageQueue 的 equeueMessage 方法将消息插入到队列
由于 Loope r的 loop 是一个死循环,当 MessageQueue 中被插入消息的时候,loop 方法就会取出 MessageQueue 中的消息,并执行 callback;而此时,Looper 是 A 线程的 Looper,进而调用的 Message 或者 Handler 的 Callback 都是执行在 A 线成中的;以此达到了线程的切换
Handler 内存泄漏的原因是什么?
通常在使用 Handler 的时候回通过匿名内部类的方式来实例化 Handler,而非静态的匿名内部类默认持有外部类的引用,即匿名内部类 Handler 持有了外部类;而导致内存泄漏的根本原因是是因为 Handler 的生命周期与宿主的生命周期不一致
- 比如说在 Activity 中实例化了一个非静态的匿名内部类 Handler,然后通过 Handler 发送了一个延迟消息,但是在消息还未执行时结束了 Activity
- 此时由于 Handler 持有 Activity,就会导致 Activity 无法被 GC 回收,也就是出现了内存泄漏的问题
什么是 Binder?
直观来说,Binder 是 Android 中的一个类,它继承了 IBinder 接口
- 从 IPC 角度来说: Binder 是 Android 中的一种跨进程通信方式,Binder 还可以理解为一种虚拟的物理设备,它的设备驱动是 /dev/binder,该通信方式在 linux 中没有
- 从 Android Framework 角度来说:Binder 是 ServiceManager 连接各种 Manager(ActivityManager、WindowManager,etc)和相应ManagerService 的桥梁
- 从 Android 应用层来说: Binder 是客户端和服务端进行通信的媒介,当你 bindService 的时候,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于 AIDL 的服务
为什么要使用 Binder?
- 性能: 移动设备中如果广泛的使用跨进程通信机制肯定会对通信机制提出严格的要求,而 Binder 相比较传统的进程通信方式更加的高效
- 安全:由于传统进程通信方式没有对通信的双方和身方做出严格的验证,只有上层协议才会去架构,如 socket 连接的 IP 地址可以人为的伪造;而 Binder 身份校验也是 android 权限模式的基础
Binder 的工作流程是什么样的?
- 性客户端首先获取服务器端的代理对象,所谓的代理对象实际上就是在客户端建立一个服务端的“引用”,该代理对象具有服务端的功能,使其在客户端访问服务端的方法就像访问本地方法一样
- 性客户端通过调用服务器代理对象的方式向服务器端发送请求
- 性代理对象将用户请求通过 Binder 驱动发送到服务器进程
- 性服务器进程处理用户请求,并通过 Binder 驱动返回处理结果给客户端的服务器代理对象
随着面试过程中你的回答,面试官就会联想到更多的技术知识点,以此来了解你的技术面有多广,适不适合该职位,或者能不能往更高的职位上发展,全方位地考察你对技术的理解深度,以及解决问题的能力
为了帮助大家更好学习 Android Framework 框架层必备的底层逻辑,技术原理,源码解析,面试真题等等技术知识点相关的问题,这里特别提供一份由腾讯大佬所整理的一张 Android Framework 思维导图及其配套的一份学习手册;有需要思维导图及学习手册的朋友: 可以简信发送 “进阶” 即可 直达获取;希望大家看完之后,能够查漏补缺
思维导图及学习手册内容展示如下:
Android Framework 思维导图
高清版 Android Framework 思维导图 获取方式: 简信发送 "进阶" 即可 直达获取
从源码角度谈谈 Handler 的应用
- Handler 的应用
- 线程间的通讯
- 实现延时操做
- 使用
HandlerThread
在异步线程执行耗时操做 - 使用
Handler
机制检测应用中的卡顿问题 - Handler 使用注意事项
Handler 机制之 Thread
- 线程概念
- Android 线程的实现
- 线程的阻塞
- 关于线程上下文切换
- 关于线程的安全问题
- 守护线程
- 线程的内存
完整版 Android Framework 思维导图及学习手册 获取方式: 简信发送 "进阶" 即可 直达获取
Handler 机制之 ThreadLocal
- Java 中的 ThreadLocal
- ThreadLocal 的前世今生
- Android 中的 ThreadLocal
- Android 面试中的关于 ThreadLocal 的问题
- ThreadLocal 的结构
- ThreadLocal 静态类 ThreadLocal.Values
- ThreadLocal 的总结
应用程序与 AMS 的通讯实现
- 从应用程序进程到管理者进程
- 应用程序进程向管理者进程发送消息
- 从管理者进程到应用程序进程
- 管理者进程向应用程序进程发送消息
- 用户进程接收消息
完整版 Android Framework 思维导图及学习手册 获取方式: 简信发送 "进阶" 即可 直达获取
应用进程与 WMS 的通讯实现
- WindowManagerImpl & WindowManagerGlobal
- ViewRootImpl
- 从应用进程到管理者进程
- 从管理者进程到应用进程
应用进程之间的通讯实现
- 服务端编写 AIDL 文件
- 编写 Service
- 声明 Service
- 客户端编写 AIDL 文件
- 绑定服务,并调用
- IBinder实现原理
完整版 Android Framework 思维导图及学习手册 获取方式: 简信发送 "进阶" 即可 直达获取
机遇往往是留给有准备的人,一个好的机遇往往就能让你一飞冲天;但机遇即使到了你身边,你却没有能力留住它,那么它还是会从你的身边溜走,所以我们一定要在有限的时间内,将自己的技术打磨好,不断的吸取新知识,努力提升自己的知识水平和技术层次,只有这样,你才能在机遇降临到你身边的时候,你才能够牢牢的抓住它
既然选择了程序员这个行业,那么你一定要做好充足的准备;要想在人前显贵,背后所付出的辛劳和汗水就是必须的
Android 架构师之路还能漫长,与君共勉
网友评论