Android 面试题 + 答案(含初级 / 中级 / 高级分级)
1. Android 四大组件是什么?分别有什么作用?
答案:
Android 四大组件包括:
Activity:负责界面展示和用户交互。Service:负责在后台执行耗时任务,不提供界面。BroadcastReceiver:用于接收系统或应用发送的广播消息。ContentProvider:用于实现应用间的数据共享。
这四大组件通常通过Intent建立联系,构成 Android 应用的核心运行结构。
2. Activity 的生命周期有哪些?
答案:
常见生命周期方法包括:
onCreate():初始化界面和数据。onStart():界面对用户可见。onResume():界面进入前台,可与用户交互。onPause():界面失去焦点,通常用于保存轻量数据。onStop():界面完全不可见。onDestroy():Activity 被销毁前调用。onRestart():从停止状态重新启动时调用。
面试中要特别说明:
- 从 A 页面跳到 B 页面时,A 会先执行
onPause()。 - 如果 A 完全不可见,则继续执行
onStop()。 - 当系统内存不足时,处于停止状态的 Activity 可能被系统回收。
3. Activity 和 Fragment 的区别是什么?
答案:
Activity是页面级组件,Fragment更像可复用的界面模块。- 一个
Activity可以包含多个Fragment。 Fragment生命周期依赖宿主Activity,但有自己独立的方法,如onCreateView()、onDestroyView()。- 在复杂 UI、平板适配、模块化开发中,
Fragment更灵活。
简单来说:Activity更偏页面容器,Fragment更偏页面内容单元。
4. Service 的两种启动方式是什么?
答案:
Service主要有两种启动方式:
startService()/startForegroundService():启动后会在后台长期运行,与调用者无直接绑定关系,需要手动停止。bindService():调用者与 Service 绑定,可进行进程内通信,调用者销毁后通常会解绑。
补充:
- Android 8.0 以后后台启动服务受限,很多场景需要使用前台服务。
- 如果只是做可延迟、可调度的后台任务,更推荐使用
WorkManager。
5. BroadcastReceiver 的使用场景有哪些?
答案:
常见场景包括:
- 监听网络变化
- 监听开机完成
- 监听电量变化
- 接收自定义广播进行组件间通信
注意点:
- 广播分为静态注册和动态注册。
- Android 8.0 后对隐式广播做了很多限制。
- 广播中不能做耗时操作,否则容易导致 ANR。
6. ContentProvider 有什么作用?
答案:
ContentProvider主要用于不同应用之间共享数据。它对外提供统一的数据访问接口,常通过Uri标识数据。
常见操作方法有:
query()insert()update()delete()getType()
例如系统通讯录、媒体库等,都是通过ContentProvider暴露数据的。
7. 什么是 ANR?产生原因有哪些?
答案:
ANR 全称是Application Not Responding,表示应用无响应。
常见触发原因:
- 主线程执行耗时操作,如网络请求、数据库大查询、文件读写
- 主线程被锁阻塞
BroadcastReceiver或Service执行时间过长
常见超时场景:
- Activity 输入事件响应超时
- BroadcastReceiver 处理超时
- Service 执行超时
避免方式:
- 耗时任务放到子线程
- 减少主线程复杂计算
- 合理使用异步机制,如协程、线程池、WorkManager
8. 什么是 OOM?常见原因有哪些?
答案:
OOM 即OutOfMemoryError,表示内存溢出。
常见原因:
- 大图加载未压缩
- Bitmap 未及时回收
- 集合类持有大量对象
- 单例、静态变量、非静态内部类导致内存泄漏
- 页面销毁后对象仍被引用
优化方式:
- 图片按需压缩和采样
- 使用图片加载框架,如 Glide、Coil
- 避免内存泄漏
- 及时释放不再使用的资源
9. 什么是内存泄漏?常见场景有哪些?
答案:
内存泄漏指对象已经不再使用,但仍然被引用,导致 GC 无法回收。
常见场景:
- 单例持有 Activity Context
- Handler 持有外部 Activity 引用
- 匿名内部类或非静态内部类持有外部类引用
- 注册监听后未反注册
- 静态集合持有页面对象
正确做法:
- 尽量使用
ApplicationContext - Handler 使用静态内部类 +
WeakReference - 在合适生命周期中解绑监听、取消回调
10. Handler 的原理是什么?
答案:
Handler的核心机制是消息队列模型,涉及:
Message:消息对象MessageQueue:消息队列Looper:不断从队列中取消息并分发Handler:发送和处理消息
工作流程:
- 线程先调用
Looper.prepare()创建 Looper 和 MessageQueue。 - 通过
Handler发送消息到 MessageQueue。 Looper.loop()不断取出消息。Handler的handleMessage()处理消息。
主线程默认已经创建好 Looper,因此可以直接创建 Handler。
11. 为什么不能在子线程直接更新 UI?
答案:
Android 的 UI 控件不是线程安全的。如果多个线程同时修改 UI,容易导致状态不一致和异常。
因此 Android 规定只有主线程可以更新 UI。子线程如果要更新界面,通常需要通过:
HandlerrunOnUiThread()View.post()LiveData- Kotlin 协程切回主线程
12. Thread、HandlerThread、AsyncTask、线程池有什么区别?
答案:
Thread:最基础的线程,适合简单异步任务。HandlerThread:带有消息循环的线程,适合串行处理任务。AsyncTask:早期用于异步任务封装,但现在已被废弃,不推荐使用。ThreadPoolExecutor:线程池,可复用线程,适合统一管理并发任务。
面试中建议补充:
- 现代 Android 更推荐使用 Kotlin 协程处理异步任务。
- 对于可调度后台任务,推荐
WorkManager。
13. Serializable 和 Parcelable 的区别是什么?
答案:
Serializable是 Java 提供的序列化接口,使用简单,但性能较差。Parcelable是 Android 提供的序列化方式,性能更好,更适合组件间传递数据。
区别总结:
Serializable通过反射实现,开销较大。Parcelable需要手动实现读写逻辑,但效率更高。
在 Android 面试中,通常会回答:组件间传输数据优先使用 Parcelable。
14. Intent 显式调用和隐式调用的区别是什么?
答案:
- 显式 Intent:明确指定目标组件,如指定具体 Activity 类名。
- 隐式 Intent:不指定具体组件,由系统根据
action、category、data匹配合适组件。
例如:
- 打开本应用某个页面,通常用显式 Intent。
- 打开浏览器、拨号、分享内容,通常用隐式 Intent。
15. 什么是启动模式?有哪些类型?
答案:
Activity 启动模式有 4 种:
standard:默认模式,每次都会创建新实例。singleTop:如果目标 Activity 已位于栈顶,则复用。singleTask:如果任务栈中已存在该 Activity,则复用并清除其上的页面。singleInstance:独占一个任务栈,使用较少。