前言
本文整理了 Android 开发岗位在大厂面试中的常见问题,涵盖核心组件、系统原理及性能优化等方面。
1. Activity
- Activity 的启动流程
- onSaveInstanceState()、onRestoreInstanceState() 的调用时机
- Activity 的启动模式和使用场景
- Activity A 跳转 Activity B,再按返回键,生命周期执行的顺序
- 横竖屏切换、按 home 键、按返回键、锁屏与解锁屏幕、跳转透明 Activity 界面、启动一个 Theme 为 Dialog 的 Activity,弹出 Dialog 时 Activity 的生命周期
- onStart 和 onResume、onPause 和 onStop 的区别
- Activity 之间传递数据的方式,Intent 是否有大小限制,如果传递的数据量偏大,有哪些方案
- Activity 的 onNewIntent() 方法什么时候会执行
- 显示启动和隐式启动
- scheme 使用场景、协议格式、如何使用
- ANR 的四种场景
- onCreate 和 onRestoreInstance 方法中恢复数据时的区别
- Activity 间传递数据的方式
- 跨 App 启动 Activity 的方式、注意事项
- Activity 任务栈是什么
- 有哪些 Activity 常用的标记位 Flags
- Activity 的数据是怎么保存的,进程被 Kill 后,保存的数据怎么恢复的
2. Service
- Service 的生命周期,两种启动方式的区别
- Service 启动流程
- Service 与 Activity 怎么实现通信
- IntentService 是什么,IntentService 原理,应用场景及其与 Service 的区别
- Service 的 onStartCommand 方法有几种返回值?各代表什么意思?
- bindService 和 startService 混合使用的生命周期以及怎么关闭
3. BroadcastReceiver
- 广播的分类和使用场景
- 广播的两种注册方式的区别
- 广播发送和接收的原理
- 本地广播和全局广播的区别
4. ContentProvider
- 什么是 ContentProvider 及其使用
- ContentProvider 与 ContentObserver 之间的关系
- ContentProvider 的实现原理
- ContentProvider 的优点
- Uri 是什么
5. Handler
- Handler 的实现原理
- 子线程中能不能直接 new 一个 Handler,为什么主线程可以?主线程的 Looper 第一次调用 loop 方法,什么时候,哪个类?
- Handler 导致的内存泄露原因及其解决方案
- 一个线程可以有几个 Handler,几个 Looper,几个 MessageQueue 对象
- Message 对象创建的方式有哪些及区别?Message.obtain() 如何维护消息池?
- Handler 有哪些发送消息的方法
- Handler 的 post 与 sendMessage 的区别和应用场景
- Handler postDelay 后有什么变化,假设先 postDelay 10s,再 postDelay 1s,怎么处理这 2 条消息
- MessageQueue 是什么数据结构
- Handler 怎么做到的一个线程对应一个 Looper,如何保证只有一个 MessageQueue,ThreadLocal 在 Handler 机制中的作用
- HandlerThread 是什么?好处?原理?使用场景?
- IdleHandler 及其使用场景
- 消息屏障,同步屏障机制
- 子线程能不能更新 UI
- 为什么 Android 系统不建议子线程访问 UI
- Android 中为什么主线程不会因为 Looper.loop() 里的死循环卡死,MessageQueue#next 在没有消息的时候会阻塞,如何恢复?
- Handler 消息机制中,一个 Looper 是如何区分多个 Handler 的,当 Activity 有多个 Handler 的时候,怎么样区分当前消息由哪个 Handler 处理,处理 message 的时候怎么知道是去哪个 callback 处理的
- Looper.quit/quitSafely 的区别
- 通过 Handler 如何实现线程的切换
- Handler 如何与 Looper 关联的
- Looper 如何与 Thread 关联的
- Looper.loop() 源码
- MessageQueue 的 enqueueMessage() 方法如何进行线程同步的
- MessageQueue 的 next() 方法内部原理
- 子线程中是否可以用 MainLooper 去创建 Handler,Looper 和 Handler 是否一定处于一个线程
- ANR 和 Handler 的联系
6. View 绘制
- View 绘制流程
- MeasureSpec 是什么
- 子 View 创建 MeasureSpec 创建规则是什么
- 自定义 View wrap_content 不起作用的原因
- 在 Activity 中获取某个 View 的宽高有几种方法
- 为什么 onCreate 获取不到 View 的宽高
- View.post 与 Handler.post 的区别
- Android 绘制和屏幕刷新机制原理
- Choreography 原理
- 什么是双缓冲
- 为什么使用 SurfaceView
- 什么是 SurfaceView
- View 和 SurfaceView 的区别
- SurfaceView 为什么可以直接在子线程绘制
- SurfaceView、TextureView、SurfaceTexture、GLSurfaceView 的区别
- getWidth() 方法和 getMeasuredWidth() 区别
- invalidate() 和 postInvalidate() 的区别
- requestLayout、onLayout、onDraw、drawChild 区别与联系
- LinearLayout、FrameLayout 和 RelativeLayout 的性能对比
- LinearLayout 的绘制流程
- 自定义 View 的流程和注意事项
- 自定义 View 如何考虑机型适配
- 自定义控件优化方案
- invalidate 如何实现局部刷新
- View 加载流程(setContentView)
7. View 事件分发
- View 事件分发机制
- View 的 onTouchEvent、OnClickListener 和 OnTouchListener.onTouch 方法优先级
- onTouch 和 onTouchEvent 的区别
- ACTION_CANCEL 何时触发
- 事件是先到达 DecorView 还是 Window
- 点击事件被拦截,但希望传递到下层 View 如何处理
- 如何解决 View 的事件冲突
- 在 ViewGroup 的 onTouchEvent 中消费 ACTION_DOWN 事件,ACTION_UP 事件如何传递
- Activity、ViewGroup 和 View 都不消费 ACTION_DOWN,ACTION_UP 事件如何传递
- 同时给父 View 和子 View 设置点击方法,谁优先响应
- requestDisallowInterceptTouchEvent 的调用时机
8. RecyclerView
- RecyclerView 的多级缓存机制及各级缓存的作用与场景
- RecyclerView 的滑动回收复用机制
- RecyclerView 的刷新回收复用机制
- RecyclerView 为何需要预布局
- ListView 与 RecyclerView 的区别
- RecyclerView 性能优化
9. ViewPager & Fragment
- Fragment 的生命周期及与 Activity 生命周期的关系
- Activity 和 Fragment 的通信方式,Fragment 之间的通信
- 为何使用 Fragment.setArguments(Bundle) 传递参数
- FragmentPagerAdapter 和 FragmentStatePagerAdapter 的区别及使用场景
- Fragment 懒加载
- ViewPager2 与 ViewPager 的区别
- Fragment 嵌套问题
10. WebView
- 如何提高 WebView 加载速度
- WebView 与 JS 的交互
- WebView 的安全漏洞
- JSBridge 原理
11. 动画
- 动画类型
- 补间动画和属性动画的区别
- ObjectAnimator 与 ValueAnimator 的区别
- TimeInterpolator 插值器及自定义插值器
- TypeEvaluator 估值器
12. Bitmap
- Bitmap 内存占用计算
- getByteCount() 与 getAllocationByteCount() 的区别
- Bitmap 的压缩方式
- LruCache 与 DiskLruCache 原理
- 如何设计一个图片加载库
- 如何加载超大尺寸图片
- 将 drawable-xxhdpi 下的图片移动到 drawable-xhdpi 下,内存变化分析
- 不同密度下图片加载优先级及分辨率适配策略
13. MVC & MVP & MVVM
- MVC 架构及其优缺点
- MVP 架构及其优缺点
- MVVM 架构及其优缺点
- MVP 中 Presenter 生命周期管理及网络请求取消
14. Binder
- Android 中进程和线程的关系及区别
- 为何需要 IPC 及多进程通信潜在问题
- Android 中 IPC 方式种类及优缺点
- 为何选择 Binder 作为主要 IPC 方式
- Binder 简介
- Binder 原理及内核空间一次拷贝机制
- 使用 Binder 传输数据的具体流程
- Binder 框架中 ServiceManager 的作用
- AIDL 简介
- AIDL 使用步骤
- AIDL 支持的数据类型
- AIDL 的关键类、方法和工作流程
- 多模块使用 AIDL 的优化方案
- Binder 传输数据的大小限制及超限后果
- Binder 驱动加载的重要步骤
- 系统服务与 bindService 启动服务的区别
- Activity 的 bindService 流程
- 不通过 AIDL 手动实现 Binder 通信
15. 内存泄漏 & 内存溢出
- OOM 与内存泄漏的定义及原因
- Thread 导致内存泄露的原因及解决
- Handler 导致内存泄露的原因及解决
- 加载 Bitmap 防止内存溢出的方法
- MVP 中处理 Presenter 层防止内存泄漏的方法
16. 性能优化
- 内存优化
- 启动优化
- 布局加载和绘制优化
- 卡顿优化
- 网络优化
17. Window & WindowManager
- Window 简介
- WindowManager 简介
- ViewRootImpl 简介
- DecorView 简介
- Activity、View、Window 三者关系
- DecorView 何时被 WindowManager 添加到 Window
18. WMS
- WMS 简介
- WMS 管理 Window 的机制
- IWindowSession 及 WindowSession 创建过程
- WindowToken 简介
- WindowState 简介
- Android 窗口分类及分组原理
- Dialog 的 Context 限制
- App 与 SurfaceFlinger 通信及 View 数据传递
- 共享内存的具体实现
- relayout 向 SurfaceFlinger 申请 Surface 的过程
- Surface 简介
19. AMS
- ActivityManagerService 简介、初始化及作用
- ActivityThread 与 ApplicationThread 的区别
- Instrumentation 简介及与 ActivityThread 的关系
- ActivityManagerService 与 Zygote 进程通信实现
- ActivityRecord 与 ProcessRecord
- ActivityManager 与 ActivityManagerProxy 的关系
- 手写简化版 AMS
20. 系统启动
- Android 系统启动流程
- SystemServer、ServiceManager、SystemServiceManager 的关系
- 为何由 Zygote 而非 SystemServer 孵化应用进程
- Zygote 的 IPC 通信机制为何使用 Socket
21. App 启动 & 打包 & 安装
- 应用启动流程
- APK 组成及 Android 打包流程
- Android 签名机制及 V1/V2 版本差异
- APK 安装流程
22. 序列化
- 序列化简介
- 为何需要序列化和反序列化
- 序列化的好处
- Serializable 与 Parcelable 的区别
- serialVersionUID 简介
- 为何显式指定 serialVersionUID 的值

