跳到主要内容Android 中高级开发工程师面试核心知识点总结 | 极客日志Java大前端java
Android 中高级开发工程师面试核心知识点总结
Android 中高级开发面试重点考察组件机制、内存管理及性能优化能力。内容涵盖 Activity 生命周期与启动模式、Service 绑定与保活、ContentProvider 数据共享、Handler 消息机制及 Java 基础原理。通过解析常见问题与底层逻辑,帮助开发者建立系统化知识框架,应对大厂技术考核。
Qiny0119 浏览 Android 中高级开发工程师面试核心知识点总结
Activity
什么是 Activity?
Activity 是 Android 应用的基本组件之一,代表一个单一的屏幕界面。它是用户与应用程序交互的入口点,每个 Activity 都对应一个窗口。
Activity 生命周期
Activity 的生命周期包含以下关键方法:
onCreate(): 创建时调用,用于初始化。
onStart(): 变为可见时调用。
onResume(): 开始与用户交互时调用。
onPause(): 失去焦点但不可见时调用,常用于保存数据。
onStop(): 完全不可见时调用。
onDestroy(): 销毁前调用,释放资源。
onRestart(): 从停止状态重新启动时调用。
Activity 的四个状态
- 运行中 (Running): 处于前台,用户可见。
- 暂停 (Paused): 部分可见或被遮挡,但仍保留在内存。
- 停止 (Stopped): 完全不可见,可能被系统回收。
- 销毁 (Destroyed): 已移除或进程结束。
Context 的区别
- Context: 上下文环境,提供访问资源、启动组件等能力。
- Activity: 继承自 ContextThemeWrapper,拥有 UI 和生命周期。
- Application: 整个应用的上下文,生命周期最长,适合存储全局单例。
Activity 启动模式
四种模式:standard, singleTop, singleTask, singleInstance。
- singleTop: 栈顶复用,若实例已在栈顶则不新建。
- singleTask: 栈内唯一,查找时清除下方所有任务。
书签通常使用 singleTop 避免重复堆叠,而不用 singleTask 是因为后者会改变任务栈结构,可能影响导航体验。
Activity 退出与安全退出
- 单个退出:调用
finish()。
- 安全退出:维护一个 Activity 栈,遍历调用 finish() 并清空引用,防止内存泄漏。
Activity-Window-View 关系
Activity 持有 Window 对象,Window 管理 ViewRoot。View 树通过 Window 绘制到屏幕上。三者层层封装,实现 UI 渲染。
Broadcast Receiver
注册方式
- 静态注册: 在 Manifest 中声明,无需代码即可接收广播,即使应用未启动。
- 动态注册: 代码中 registerReceiver,需手动 unregister,生命周期随组件。
优缺点
- 静态:持久性强,但占用资源多,无法灵活控制。
- 动态:灵活,受生命周期管理,但易忘注销导致泄漏。
广播类型
标准广播:全量接收,效率低。有序广播:按优先级依次执行,可中断。本地广播:仅应用内传递,安全高效。注意事项
BroadcastReceiver 中不能执行耗时操作,否则会导致 ANR。应使用 IntentService 或异步线程处理。
Service
启动与绑定
- 启动:
startService(),独立运行,需 stopService() 停止。
- 绑定:
bindService(),与组件生命周期绑定,可通信。
生命周期
onCreate(), onStartCommand(), onBind(), onUnbind(), onDestroy()。
线程模型
Service 默认在主线程运行,不能执行耗时操作(如网络请求),需开启子线程或使用 Handler/AsyncTask。
IntentService
继承自 Service,自动处理消息队列,执行完自动停止,适合后台任务。
ContentProvider
数据存储方式
SQLite、SharedPreferences、文件存储、ContentProvider。
批量操作
通过 ContentResolver 调用 applyBatch() 进行事务性批量更新。
组件关系
- ContentProvider: 数据提供者。
- ContentResolver: 客户端接口,负责查询。
- ContentObserver: 监听数据变化。
数据共享
通过 URI 标识数据源,跨进程访问数据库,实现安全的数据交换。
Intent
Intent 与 Filter
Intent 描述动作,Filter 定义匹配规则。隐式 Intent 依赖 Filter 匹配组件。
数据类型
支持基本类型、String、Serializable、Parcelable 及 Bundle 包装的对象。
Serializable vs Parcelable
- Serializable: Java 原生,反射机制,性能较低。
- Parcelable: Android 专用,手写序列化,性能高,推荐用于跨组件传输。
显式与隐式
- 显式: 指定目标类名,用于内部跳转。
- 隐式: 指定 Action/Category/MIME,用于系统或外部组件调用。
ListView
数据集更新
调用 adapter.notifyDataSetChanged() 刷新视图。
分页加载
监听滚动到底部事件,触发下一页数据加载并追加至列表。
局部刷新
定位特定位置 Item,获取 ViewHolder 后更新内容,避免整体重绘。
图片优化
使用 Glide 或 Picasso 库,设置缓存策略,压缩图片尺寸,避免 OOM。
点击失效问题
Item 中包含 Button 时,需设置 focusable="false" 或 clickable="false",防止拦截点击事件。
效率优化
复用 ViewHolder,减少 findViewById 调用;避免复杂布局嵌套。
多种条目类型
重写 getItemViewType() 和 getViewTypeCount(),根据类型返回不同布局。
定位指定位置
调用 listView.setSelection(position)。
ScrollView 嵌入
禁止 ScrollView 嵌套 ListView,可使用 CustomScrollView 或 RecyclerView 替代。
图片错位
通常因图片加载异步导致高度计算错误,需预加载或固定高度。
setEmptyView
Fragment
切换与实例化
使用 replace() 或 show()/hide() 切换,避免重复实例化。
优点
栈管理
通过 FragmentTransaction 的 addToBackStack() 实现压栈出栈效果。
replace 与 add
- replace: 替换当前容器内容。
- add: 叠加添加,需配合 hide/show 管理可见性。
传值
通过 setArguments() 传递 Bundle 参数。
生命周期
与宿主 Activity 关联,注意 onAttach(), onCreateView(), onResume() 等回调顺序。
ViewPager 会预加载相邻 Fragment,需注意资源释放,避免内存泄漏。
Java 基础
重载与重写
- 重载: 同名不同参,编译期绑定。
- 重写: 子类覆盖父类方法,运行时多态。
String 系列
- String: 不可变,常量池。
- StringBuffer: 可变,线程安全。
- StringBuilder: 可变,非线程安全,性能更高。
设计模式
常见包括单例、工厂、观察者、代理、适配器、装饰者等。
TCP/IP 分层
应用层 (HTTP), 传输层 (TCP), 网络层 (IP), 链路层。
final 关键字
- final: 修饰变量不可改,类不可继承,方法不可重写。
- finally: 异常处理块,无论是否捕获均执行。
- finalize: 垃圾回收前调用,已过时。
int 与 Integer
- int: 基本类型,默认 0。
- Integer: 包装类,默认 null,涉及自动装箱拆箱。
equals 与 hashCode
- equals: 比较内容。
- hashCode: 哈希值,用于 Map/Set 索引,需与 equals 保持一致。
性能优化
性能分析
使用 Systrace, Profiler, LeakCanary 等工具分析 CPU、内存、网络。
内存泄露原因
静态集合持有 Context、未注销监听器、单例长生命周期引用短对象。
OOM 原因
大对象未释放、循环引用、Bitmap 过大、内存碎片。
static 解决方案
避免 static 持有 Activity 引用,使用 Application Context。
线程 OOM
OOM 异常处理
图片 OOM
异常捕获
全局 UncaughtExceptionHandler 捕获未处理异常,上报崩溃信息。
ANR 处理
主线程耗时超过 5s,优化 IO 操作,使用异步线程,避免死锁。
通信机制
- 线程间: Handler, Looper, MessageQueue。
- 进程间: Binder, AIDL, Messenger。
进程区别
- Devik: 开发调试进程。
- Linux 进程: 操作系统调度单元。
- 线程: 进程内执行流,共享内存。
线程通信方式
Handler, SharedMemory, Socket, Pipe。
内存合理使用
屏幕适配+AIDL
适配方式
dp/sp 单位,密度无关,使用 ConstraintLayout,适配不同分辨率。
AIDL 基础
Android Interface Definition Language,定义跨进程接口。
工作原理
通过 Binder 机制生成 Stub 和 Proxy,实现远程调用。
数据类型
支持基本类型、String、List、Map 及自定义 Parcelable 对象。
动画
动画分类
补间动画 (Tween) 和帧动画 (Frame)。
组合使用
可组合多个 Tween 动画,如 Alpha + Translate。
插值器
AccelerateDecelerate, Linear, Overshoot, Anticipate 等。
自定义插值器
继承 Interpolator,重写 getInterpolation 方法。
窗口动画
在 styles.xml 中定义 windowEnterAnimation 和 exitAnimation。
事件处理
Handler 机制
MessageQueue 队列,Looper 循环取消息,Handler 发送和处理。
onTouch 与 onTouchEvent
- onTouch: 触摸事件分发,可拦截。
- onTouchEvent: 具体事件处理。
子线程 new Handler
可以,但需确保 Looper 存在,否则报错。建议主线程创建。
子线程更新 UI
除 Handler 外,可用 runOnUiThread, LiveData, Coroutine。
子线程访问 UI
其他
框架平台
常用 Retrofit, OkHttp, Glide, Dagger, RxJava 等。
三级缓存
内存缓存 (LruCache)、磁盘缓存 (DiskLruCache)、网络缓存。
清除缓存
推送好处
JSON 传输
项目流程
需求分析->设计->开发->测试->上线->运维。
自定义 View
测量、布局、绘制三步走,重写 onMeasure, onLayout, onDraw。
Retrofit 使用
组件化优势
插件化优势
打包原理
安装流程
下载 APK->校验签名->解压->安装->启动。
防反编译
签名版本
v1 基于 JAR 签名,v2 基于整包签名,安全性更高。
加密方式
对称加密 (AES) 速度快,非对称加密 (RSA) 更安全,常结合使用。
进程保活
双进程守护,系统广播监听,前台服务,JobScheduler。
Binder 优势
URI 与 URL
URI 统一资源标识符,URL 统一资源定位符,URL 是 URI 的子集。
TLS/SSL 握手
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online