
一、前言:Android 面试考什么?
Android 面试的经典结构是:Java/Kotlin 基础 → Android 四大组件 → 消息机制 → View 体系 → 性能优化 → 项目深挖。其中 Android 特有的部分集中在中间三块,也是本文重点。

以下 25 道高频题按模块整理,每题给出标准答案 + 追问点,背熟能覆盖 80% 的一二面。
二、四大组件
Q1:Activity 的生命周期?异常情况呢?
标准答案:
正常启动:onCreate → onStart → onResume
退到后台:onPause → onStop
回到前台:onRestart → onStart → onResume
销毁: onPause → onStop → onDestroy
异常生命周期(横竖屏切换):
Activity 被销毁重建,走 onPause → onStop → onSaveInstanceState → onDestroy → onCreate → onStart → onRestoreInstanceState → onResume。
数据保存:在 onSaveInstanceState(Bundle) 里存临时数据,onCreate / onRestoreInstanceState 里恢复。
追问点:onPause 里能做耗时操作吗?——不能,新 Activity 的 onResume 要等上一个 onPause 执行完(应用层如此),卡这里会掉帧。
Q2:Activity 的四种启动模式?
| standard | 每次新建实例入栈 | 默认 |
| singleTop | 栈顶存在则复用(走 onNewIntent) | 推送详情页,防连点开 N 个 |
| singleTask | 栈内存在则清其上所有 Activity | 主页 |
| singleInstance | 独占一个任务栈 | 通话、来电页 |
追问点:singleTask + 不同任务栈(taskAffinity)的行为;onNewIntent 生命周期顺序(onNewIntent → onRestart → onStart → onResume)。
Q3:Service 的 startService 和 bindService 区别?
| 生命周期 | onCreate → onStartCommand,需主动 stopSelf/stopService | onCreate → onBind → onUnbind → onDestroy |
| 与调用者关系 | 无关联,调用者销毁 Service 还活着 | 绑定共存亡,可拿到 IBinder 通信 |
| 用途 | 后台下载、播放 | 与 Activity 交互(如音乐进度条) |
追问点:Android 8.0 后台 Service 限制 → 前台服务(startForeground + 通知);保活为什么靠 Service 靠不住。
Q4:广播的有序广播和无序广播?
- 普通广播(sendBroadcast):异步,所有接收者几乎同时收到,不可拦截。
- 有序广播(sendOrderedBroadcast):按优先级依次传递,可 abortBroadcast() 截断、可修改结果。
- 本地广播(LocalBroadcastManager):仅应用内,安全高效(官方已废弃,推荐用 EventBus/Flow 替代)。
追问点:静态注册广播在 Android 8.0 后的限制(大部分系统广播只允许动态注册)。
Q5:ContentProvider 的作用?
跨进程数据共享的标准方案。底层基于 Binder,通过 URI 定位数据(content://com.app.provider/user/1)。
追问点:为什么启动 App 时 ContentProvider 的 onCreate 先于 Application.onCreate?(initOrder 里 installContentProviders 先执行)——高频冷门题。
三、消息机制:Handler 必考五连
Q6:Handler 的完整工作原理?
标准答案(必须按链路背):
Handler.sendMessage(msg)
→ MessageQueue.enqueueMessage(msg, when) 消息入队(按时间排序)
→ Looper.loop() 死循环取消息 (主线程早有 Looper)
→ msg.target.dispatchMessage(msg) 分发给 Handler
→ handleMessage(msg) 处理
角色分工:
| Handler | 发送和处理消息 | 邮递员 |
| Message | 消息载体(含 what/obj/when/target) | 信件 |
| MessageQueue | 按时间排序的优先级队列 | 信箱 |
| Looper | 死循环取消息,驱动分发 | 邮局分拣员 |
| ThreadLocal | 每个线程存自己的 Looper | 工牌 |
Q7:主线程为什么不会因为 Looper.loop() 死循环卡死?
高频难题。答案分三层:
Q8:Message.obtain() 为什么要复用?怎么复用?
Message 内部维护一个链表池(sPool),obtain() 优先从池里取,recycle() 时清空数据挂回池头。避免高频发消息时大量创建对象触发 GC 抖动。
追问点:为什么 Message 最大缓存 50 个(MAX_POOL_SIZE);View 的滑动消息同理用 obtain。
Q9:Handler 导致内存泄漏的原因和解决?
原因:非静态内部类 Handler 隐式持有 Activity,Message 未处理时被 MessageQueue 持有 → Message → Handler → Activity,Activity 销毁了却无法回收。
解决:
Q10:IdleHandler 是什么?
MessageQueue 空闲时的回调(addIdleHandler)。用过的场景:延迟初始化非紧急任务(如日志上报),等主线程不忙了再干。追问点:ViewRootImpl 的首次绘制就依赖 IdleHandler(等消息队列空了再 measure/layout)。
四、View 体系
Q11:View 的绘制流程?
标准答案:
ViewRootImpl.performTraversals()
├── performMeasure() → onMeasure() 测量:确定 View 大小(MeasureSpec)
├── performLayout() → onLayout() 布局:确定 View 位置
└── performDraw() → onDraw() 绘制:画到屏幕(Canvas)
MeasureSpec 三种模式:
| EXACTLY | 确定大小 | match_parent / 固定 dp |
| AT_MOST | 最大不超过 | wrap_content |
| UNSPECIFIED | 不限制 | ScrollView 对子 View |
追问点:自定义 View 时 wrap_content 为什么和 match_parent 一样?——onMeasure 默认实现不处理 AT_MOST,要自己 setMeasuredDimension。
Q12:事件分发机制?
标准答案(经典 U 型图):
Activity → Window → DecorView → ViewGroup → … → View
三个核心方法:
dispatchTouchEvent() 分发
onInterceptTouchEvent() 拦截(仅 ViewGroup 有)
onTouchEvent() 消费
- 父拦截,子收不到:onInterceptTouchEvent 返回 true → 子 View 收 ACTION_DOWN 之后的系列事件 → 事件交给父的 onTouchEvent
- 子处理了,父就不处理:子 onTouchEvent 返回 true 消费 → 父不再收 MOVE/UP
- 请求父不拦截:requestDisallowInterceptTouchEvent(true)(子 View 在 DOWN 后调用)
- 滑动冲突:外部拦截法(父改 onInterceptTouchEvent 判断方向)/ 内部拦截法(子 disallow)
Q13:requestLayout / invalidate / postInvalidate 区别?
| requestLayout | 从当前节点向上到 ViewRootImpl | measure + layout + draw | 可任意(最终排到主线程) |
| invalidate | 只重绘当前 View | 只 draw(onDraw) | 必须主线程 |
| postInvalidate | 同 invalidate | 只 draw | 可子线程 |
五、性能优化
Q14:内存泄漏的常见场景和排查?
高频泄漏场景(背 6 个):
排查工具:LeakCanary(开发期自动抓)→ Memory Profiler → MAT 分析 hprof(看 GC Root 引用链)。
Q15:卡顿的排查思路?
定位:Perfetto / Systrace 抓帧 → 找掉帧的帧
归因:看主线程在干什么
├── 主线程做 IO(读 SP / 数据库)→ 移到子线程 / MMKV
├── 主线程做复杂布局 → 降层级(ConstraintLayout / merge / ViewStub)
├── 过度绘制 → 开发者选项检查,红色区域优化
└── 频繁 GC → 内存抖动,找循环里创建对象的地方
关键指标:帧耗时 16ms(60Hz)/ 8.3ms(120Hz);Vitals 的 ANR 率 < 0.47%、崩溃率 < 1%。
Q16:Bitmap 优化怎么做?
Q17:APK 包体积优化?
- 资源:图片转 WebP、无用在 R8/资源混淆(AndResGuard)压缩、按密度分包
- 代码:R8 混淆裁剪(minifyEnabled + shrinkResources)
- so:abiFilters 只留 armeabi-v7a / arm64-v8a,或按 ABI 分包
- 动态交付:App Bundle(Play)按需下载
六、Kotlin / 协程 / 新技术
Q18:协程和线程的区别?(Android 场景)
用户态轻量级"线程":挂起不阻塞线程、创建成本几十字节、结构化并发防泄漏。Android 标配用法:
viewModelScope.launch {
val user = withContext(Dispatchers.IO) { api.fetchUser() }
updateUi(user) // 自动回主线程
}
追问点:suspend 原理(状态机);launch vs async;viewModelScope 为什么安全(Activity 旋转销毁自动取消)。
Q19:Flow 和 LiveData 的区别?
| 生命周期感知 | ✅ 内置 | 需 repeatOnLifecycle 包一层 |
| 操作符 | 少(map/switchMap) | 丰富(debounce/filter/combine…) |
| 数据流类型 | 值持有 | 冷流/热流 |
| 跨层使用 | 仅 UI 层 | 数据层/领域层通用 |
结论:新项目 UI 状态用 StateFlow,数据流处理用 Flow,LiveData 只在老项目维护。
Q20:Jetpack MVVM 的完整数据流?
View(Activity/Fragment)
↕ 观察 StateFlow / LiveData
ViewModel(持有 UI 状态,不持 Context)
↕ 调用
Repository(单一数据源原则)
↙ ↘
Room(本地缓存) Retrofit(网络)
核心原则:数据单向流动(UDF)、单一数据源(SSOT)、ViewModel 不持有任何 Context。
七、冷门但常问
Q21:Android 的进程优先级?
前台进程 > 可见进程 > 服务进程 > 缓存进程(后台 LRU)
系统按优先级从低到高杀内存。追问点:为什么保活越来越难(厂商白名单 + Doze 模式 + App Standby),正路是把进程做轻。
Q22:Binder 是什么?为什么选它而不是 Socket?
Android 跨进程通信的底层机制。选 Binder 因为:一次拷贝(mmap 内存映射,Socket/管道要两次)、C/S 架构易用、进程 ID 校验安全性好。
追问点:AIDL 是 Binder 的封装;四大组件的跨进程全靠 Binder。
Q23:SP(SharedPreferences)为什么慢?替代品?
SP 首次加载同步读文件 + 全量解析 XML 到内存(主线程 wait),写入 commit 同步、apply 虽异步但 QueuedWork 可能阻塞。
替代:MMKV(mmap + protobuf,腾讯)、DataStore(Kotlin Flow,官方推荐)。
Q24:View.post 为什么能拿到 View 宽高?
post 的 Runnable 排进消息队列,执行时机在 ViewRootImpl 的 performTraversals(绘制)之后——View 测量完了自然有宽高。
Q25:为什么 onActivityCreated 被废弃了?Fragment 通信怎么做?
废弃是推动用 viewLifecycleOwner 观察数据。现代通信方式:ViewModel 共享(同一 FragmentManager scope)> 接口回调 > Result API。
八、总结:面试复习路线
第一梯队(必背):生命周期 / 启动模式 / Handler 五连 / 事件分发 / 绘制流程
第二梯队(加分):性能优化实战案例 / Binder / 协程 Flow / MVVM 数据流
第三梯队(亮点):冷启动优化 / 包体积 / 线上监控(APM)/ 跨进程方案选型
最重要的一条建议:背完标准答案后,一定要准备一个自己项目里的真实案例。比如"我们 App 启动 3s → 1.2s"的优化过程,比 25 道八股更能让面试官记住你——八股筛人,案例定薪。
参考资料
- 《Android 开发艺术探索》任玉刚(四大组件 + View 体系)
- 《Android 进阶解密》刘望舒(消息机制 + Binder)
- Google 官方文档:developer.android.com(Jetpack / 性能)
- Android 性能优化官方课:Measuring & Improving App Performance
网硕互联帮助中心





评论前必须登录!
注册