文章目录
- 概述
-
- 一、Java 基础与进阶
-
-
- 面向对象 (OOP)
-
- 1.1 三大特性
- 1.2 接口 vs 抽象类
- 1.3 内部类
-
- 集合框架
-
- 2.1 ArrayList vs LinkedList
- 2.2 HashMap vs HashTable
- 2.3 String、StringBuilder、StringBuffer
-
- 并发与多线程
-
- 3.1 线程控制方法对比
- 3.2 synchronized vs volatile
- 3.3 线程池(ThreadPoolExecutor)
-
- JVM 相关
-
- 4.1 JVM 核心作用
- 4.2 运行时数据区
-
- 泛型与反射
-
- 5.1 泛型
- 5.2 反射
-
- 类加载机制
-
- 双亲委派模型(Parent Delegation)
-
- 二、Android 核心组件与机制
-
-
- 四大组件
-
- 1.1 Activity
- 1.2 Service
- 1.3 BroadcastReceiver
- 1.4 ContentProvider
-
- View 体系与事件分发
-
- RecyclerView 与缓存机制
-
- Handler 机制与内存泄漏
-
- 三、性能优化(补充详细方案)
-
-
- 内存优化
-
- 布局优化
-
- 卡顿优化
-
- 启动优化
-
- APK 瘦身
-
- 四、架构与设计模式(补充 MVVM 实践)
-
- MVVM + Jetpack 推荐架构
- 五、开源框架原理(补充)
- 六、新技术趋势
- 七、场景题与开放性问题(补充回答模板)
-
- "请介绍最有挑战的项目"
概述
本文系统梳理了 Android 开发从基础到高级的核心知识点,涵盖 Java 基础、Android 组件、性能优化、架构设计、Framework 原理、主流框架与新技术趋势,旨在帮助中高级开发者构建完整的知识体系,高效准备技术面试,并指导实际项目开发。
适用人群 :Android 中高级工程师、面试准备者、技术面试官、团队技术负责人
建议用法:作为知识地图逐项深入,结合源码阅读与项目实践,持续迭代技术认知。
一、Java 基础与进阶
1. 面向对象 (OOP)
1.1 三大特性
特性 | 核心概念 | 作用 | 实现方式 |
---|---|---|---|
封装 | 将数据和行为封装在类中,隐藏实现细节 | 提高安全性、降低耦合、增强可维护性 | 使用 private 字段 + public getter/setter |
继承 | 子类继承父类的属性和方法(非私有) | 实现代码复用,建立类层次结构 | extends 关键字,遵循 "is-a" 关系 |
多态 | 同一接口在不同实例下表现出不同行为 | 提高扩展性与灵活性,支持模块化设计 | 方法重写 + 动态绑定(运行时决定调用哪个实现) |
多态实现机制:基于虚方法表(vtable),JVM 在运行时根据对象实际类型查找对应方法。
1.2 接口 vs 抽象类
对比项 | 接口(Interface) | 抽象类(Abstract Class) |
---|---|---|
定义关系 | "能做什么"(行为规范) | "是什么"(共性抽象) |
多继承 | 支持(Java 8+ 默认方法) | 不支持 |
成员 | 只能有常量和抽象方法(Java 8+ 支持默认/静态方法) | 可包含字段、构造器、具体方法 |
访问控制 | 所有方法默认 public |
可使用 private 、protected |
使用场景 | 定义契约、解耦、策略模式 | 共享代码、模板方法模式 |
最佳实践:
- 优先使用接口(符合"面向接口编程"原则)
- 当需要共享代码或构造逻辑时使用抽象类
- Java 8+ 可通过接口默认方法实现部分复用
1.3 内部类
类型 | 特点 | 使用场景 |
---|---|---|
成员内部类 | 持有外部类引用,可访问所有成员 | 封装辅助类,如 Iterator |
静态内部类 | 不依赖外部类实例,无隐式引用 | 工具类、Builder 模式 |
局部内部类 | 定义在方法内,作用域受限 | 复杂逻辑封装 |
匿名内部类 | 无类名,直接实现接口或继承类 | 快速实现回调、事件监听 |
注意:
- 成员内部类可能导致内存泄漏(隐式持有外部类引用),建议在
Handler
、Thread
中使用静态内部类 +WeakReference
。- 避免过度嵌套,影响可读性和维护性。
2. 集合框架
2.1 ArrayList vs LinkedList
特性 | ArrayList | LinkedList |
---|---|---|
底层结构 | 动态数组(连续内存) | 双向链表(分散内存) |
随机访问 | O(1) | O(n) |
插入/删除(中间) | O(n) | O(1) |
内存占用 | 较小(仅元素开销) | 较大(每个节点含前后指针) |
扩容机制 | 扩容 1.5 倍,触发 Arrays.copyOf |
无固定容量,动态添加节点 |
选择建议:
- 频繁读取 →
ArrayList
- 频繁插入删除 →
LinkedList
- Android 中推荐
ArrayList
,因缓存局部性更好,GC 更友好。
2.2 HashMap vs HashTable
特性 | HashMap | HashTable |
---|---|---|
线程安全 | ❌ 非线程安全 | ✅ 方法加 synchronized |
性能 | 更高(无同步开销) | 较低 |
Null 值 | 允许一个 null 键和多个 null 值 | 不允许 null 键或值 |
迭代器 | Fail-fast(快速失败) | Fail-safe(安全失败) |
替代方案 | ConcurrentHashMap (推荐) |
已过时,不建议使用 |
HashMap 优化(JDK 8+):
- 当链表长度 ≥ 8 且哈希表容量 ≥ 64 时,链表转为红黑树,查找复杂度从 O(n) 降为 O(log n)。
- 容量始终为 2 的幂,便于通过位运算
(n - 1) & hash
计算索引。
2.3 String、StringBuilder、StringBuffer
类型 | 线程安全 | 性能 | 使用场景 |
---|---|---|---|
String |
不可变 | 低(频繁拼接产生大量对象) | 少量操作、常量 |
StringBuffer |
同步 | 中等 | 多线程环境拼接 |
StringBuilder |
非同步 | 高 | 单线程大量拼接(推荐) |
原理 :
String
是 final 类,每次拼接都会创建新对象;后两者基于可变字符数组(char[]
)实现。
3. 并发与多线程
3.1 线程控制方法对比
方法 | 是否释放锁 | 是否让出 CPU | 用途 |
---|---|---|---|
sleep() |
❌ 不释放 | ✅ 让出 | 暂停线程指定时间 |
wait() |
✅ 释放 | ✅ 让出 | 等待条件满足(需 synchronized ) |
join() |
❌ 不释放 | ✅ 让出 | 等待目标线程结束 |
yield() |
❌ 不释放 | ✅ 让出 | 提示调度器让出 CPU(不保证) |
📌 关键区别 :
wait()
必须在同步块中调用,且会释放锁;sleep()
不影响锁状态。
3.2 synchronized vs volatile
特性 | synchronized | volatile |
---|---|---|
原子性 | 保证 | 不保证 |
可见性 | 保证 | 保证 |
有序性 | 保证(通过内存屏障) | 保证(禁止指令重排) |
作用范围 | 方法或代码块 | 变量 |
性能开销 | 高(阻塞、上下文切换) | 低 |
使用建议:
- 保证原子性 + 可见性 →
synchronized
或ReentrantLock
- 仅需可见性 →
volatile
(如状态标志位)
3.3 线程池(ThreadPoolExecutor)
java
new ThreadPoolExecutor(
corePoolSize, // 核心线程数
maximumPoolSize, // 最大线程数
keepAliveTime, // 空闲线程存活时间
unit, // 时间单位
workQueue, // 任务队列(BlockingQueue)
threadFactory, // 线程工厂
handler // 拒绝策略
);
任务执行流程:
- 任务提交 → 若当前线程 < corePoolSize → 创建新线程
- 否则 → 加入
workQueue
- 队列满 → 若线程 < maxPoolSize → 创建新线程
- 否则 → 触发拒绝策略(如抛出异常、丢弃任务等)
Android 推荐 :使用Executors.newFixedThreadPool()
或newSingleThreadExecutor()
,但更推荐WorkManager
处理后台任务。
4. JVM 相关
4.1 JVM 核心作用
- 实现"一次编写,到处运行"(跨平台)
- 提供字节码执行引擎
- 自动内存管理(GC)
- 安全沙箱机制
- 多线程支持
- 动态类加载与链接
4.2 运行时数据区
区域 | 线程私有 | 存储内容 | 异常 |
---|---|---|---|
程序计数器 | 私有 | 当前线程执行的字节码行号 | 无 |
虚拟机栈 | 私有 | 栈帧(局部变量、操作数栈、方法出口) | StackOverflowError / OutOfMemoryError |
本地方法栈 | 私有 | Native 方法调用 | 同上 |
Java 堆 | 共享 | 对象实例、数组 | OutOfMemoryError |
方法区 | 共享 | 类信息、常量、静态变量 | OutOfMemoryError |
Android 注意:ART 虚拟机与 JVM 有差异,如预编译(AOT)、内存模型优化等。
5. 泛型与反射
5.1 泛型
- 编译期检查 :提供类型安全,避免运行时
ClassCastException
- 类型擦除 :泛型信息在编译后被擦除,仅保留原始类型(
Object
) - 通配符 :
? extends T
(上界)、? super T
(下界)、?
(无界)
局限 :不能用于
static
字段、不能new T()
、不能用于异常类型。
5.2 反射
- 用途:运行时获取类信息、动态调用方法、修改字段
- 性能 :较慢(需解析字节码),建议缓存
Method
/Field
对象 - 与泛型结合 :可通过
getGenericReturnType()
获取泛型类型信息,部分突破类型擦除限制
应用场景:依赖注入(Dagger)、序列化(Gson)、ORM 框架(Room)
6. 类加载机制
双亲委派模型(Parent Delegation)
text
Bootstrap ClassLoader
↑
Extension ClassLoader
↑
Application ClassLoader
↑
Custom ClassLoader (e.g., Tinker)
- 流程:子加载器收到类加载请求 → 委托父加载器 → 父加载器无法加载 → 子加载器尝试加载
- 优势 :
- 安全性 :防止核心类(如
java.lang.String
)被恶意替换 - 避免重复加载:保证类的唯一性
- 一致性:同一类由同一加载器加载
- 安全性 :防止核心类(如
打破双亲委派 :JDBC 使用
Thread.currentThread().getContextClassLoader()
加载驱动,由应用类加载器完成。
二、Android 核心组件与机制
1. 四大组件
1.1 Activity
生命周期详解
生命周期 | 触发场景 | 注意事项 |
---|---|---|
onCreate() |
首次创建 | 初始化数据、绑定布局 |
onStart() |
可见但不可交互 | 准备 UI 显示 |
onResume() |
可交互(前台) | 恢复动画、传感器 |
onPause() |
失去焦点 | 保存数据、释放资源 |
onStop() |
完全不可见 | 释放 UI 相关资源 |
onDestroy() |
销毁前 | 彻底清理 |
onRestart() |
从 onStop 回到前台 |
典型场景:
- A → B(普通):
A.onPause()
→B.onCreate()
→B.onResume()
→A.onStop()
- A → B(透明):
A.onPause()
→B.onCreate()
→B.onResume()
(A 不会onStop()
)
Activity Result API
- 替代已废弃的
startActivityForResult()
- 更安全:避免内存泄漏,支持 Fragment
- 使用
ActivityResultLauncher
注册回调
kotlin
val launcher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
// 处理返回结果
}
launcher.launch("image/*")
1.2 Service
类型 | 启动方式 | 生命周期 | 适用场景 |
---|---|---|---|
Started Service | startService() |
onCreate() → onStartCommand() → onDestroy() |
长时间后台任务(下载、播放) |
Bound Service | bindService() |
onCreate() → onBind() → onUnbind() → onDestroy() |
客户端-服务端通信 |
IntentService | startService() |
基于 HandlerThread ,任务完成自动停止 |
串行执行后台任务(已废弃,推荐 WorkManager ) |
前台服务 | startForegroundService() |
必须调用 startForeground() |
长期运行任务(音乐播放、定位) |
注意 :Android 9+ 需在
AndroidManifest.xml
中声明FOREGROUND_SERVICE
权限。
1.3 BroadcastReceiver
注册方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
静态注册 | 应用未启动也可接收 | 耗电、占用系统资源 | 开机启动、网络状态变化 |
动态注册 | 灵活、可控制生命周期 | 需手动注销,否则内存泄漏 | 活动期间监听事件 |
最佳实践:
- 动态注册必须在
onDestroy()
中调用unregisterReceiver()
onReceive()
中禁止耗时操作(>10s 导致 ANR)- 使用
LocalBroadcastManager
实现应用内通信(AndroidX 已废弃,推荐LiveData
或Flow
)
1.4 ContentProvider
核心组件
- URI :
content://authority/path/id
- ContentResolver:客户端访问接口
- MIME 类型 :标识数据类型(如
vnd.android.cursor.dir/user
)
权限控制
android:readPermission
/android:writePermission
android:exported="false"
:仅限本应用访问
系统示例:
- 联系人:
content://com.android.contacts/contacts
- 相册:
content://media/external/images/media
2. View 体系与事件分发
事件分发三要素
dispatchTouchEvent()
:分发事件onInterceptTouchEvent()
:ViewGroup 拦截判断onTouchEvent()
:处理事件
滑动冲突解决
- 外部拦截法 :父容器在
onInterceptTouchEvent()
中判断是否拦截 - 内部拦截法 :子 View 调用
requestDisallowInterceptTouchEvent(true)
请求不被拦截
3. RecyclerView 与缓存机制
四级缓存
- Scrap:屏幕内临时移除的 ViewHolder(可快速复用)
- mCachedViews:最近移出屏幕的 ViewHolder(默认 2 个)
- ViewCacheExtension:开发者自定义缓存(极少使用)
- RecycledViewPool:被废弃的 ViewHolder 池(可跨 RecyclerView 共享)
性能优化:
- 使用
DiffUtil
计算最小更新集- 设置
setHasFixedSize(true)
若尺寸不变- 避免在
onBindViewHolder
中执行耗时操作
4. Handler 机制与内存泄漏
核心流程
text
Handler.send → MessageQueue.enqueue → Looper.loop → Handler.dispatch → handleMessage()
内存泄漏防护
- 使用静态内部类 +
WeakReference<Activity>
- 在
onDestroy()
中调用handler.removeCallbacksAndMessages(null)
- 使用
Lifecycle
感知组件(如LifecycleCoroutineScope
)
三、性能优化(补充详细方案)
1. 内存优化
- LeakCanary:自动检测内存泄漏
- Bitmap 复用 :使用
inBitmap
(API 19+) - 对象池 :
SparseArray
、Pools.SynchronizedPool
2. 布局优化
- 使用
ConstraintLayout
减少嵌套 <merge>
消除冗余父布局<ViewStub>
延迟加载非关键视图
3. 卡顿优化
- Systrace 分析主线程阻塞
- 使用
Choreographer
监控帧率 - 避免在
onDraw()
中创建对象
4. 启动优化
- 异步初始化:第三方 SDK 异步加载
- 延迟初始化:非关键组件延后
- ContentProvider 初始化 :避免在
onCreate()
中做耗时操作
5. APK 瘦身
方法 | 工具/配置 |
---|---|
代码压缩 | minifyEnabled true + R8 |
资源压缩 | shrinkResources true |
图片优化 | WebP、矢量图、APK 字典 |
So 库分包 | abiFilters |
四、架构与设计模式(补充 MVVM 实践)
MVVM + Jetpack 推荐架构
text
View (Activity/Fragment)
↓ (UI Events)
ViewModel
↓ (Data Request)
Repository → Local (Room) / Remote (Retrofit)
↑
LiveData / Flow
优势:生命周期安全、数据驱动、易于测试。
五、开源框架原理(补充)
框架 | 核心原理 |
---|---|
Retrofit | 动态代理 + 注解处理器生成 ServiceMethod |
OkHttp | 拦截器链(Retry、Bridge、Cache、Connect、CallServer) |
Glide | 四级缓存(内存、磁盘、活动资源、变换缓存)+ 生命周期感知 |
EventBus | 注解生成索引,通过 HandlerPoster 发送事件 |
六、新技术趋势
- Jetpack Compose:声明式 UI,取代 XML
- Kotlin 协程 :替代
AsyncTask
、RxJava
- 跨平台:Flutter(Dart)、React Native(JS)、KMM(Kotlin Multiplatform)
七、场景题与开放性问题(补充回答模板)
"请介绍最有挑战的项目"
使用 STAR 法则:
- Situation:项目背景
- Task:你的职责
- Action:采取的技术方案
- Result:量化成果(性能提升 X%)
总结:本文覆盖 Android 开发全栈知识,建议结合源码(AOSP、Jetpack)、实战项目与持续学习,构建可落地的技术能力。
下一步建议:
- 将本文作为知识地图,逐项深入
- 阅读官方文档与源码
- 参与开源项目或技术社区