Android 开发核心知识体系与面试指南精简版

160 阅读10分钟

@TOC

概述

本文系统梳理了 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可使用 privateprotected
使用场景定义契约、解耦、策略模式共享代码、模板方法模式

最佳实践

  • 优先使用接口(符合“面向接口编程”原则)
  • 当需要共享代码或构造逻辑时使用抽象类
  • Java 8+ 可通过接口默认方法实现部分复用
1.3 内部类
类型特点使用场景
成员内部类持有外部类引用,可访问所有成员封装辅助类,如 Iterator
静态内部类不依赖外部类实例,无隐式引用工具类、Builder 模式
局部内部类定义在方法内,作用域受限复杂逻辑封装
匿名内部类无类名,直接实现接口或继承类快速实现回调、事件监听

注意

  • 成员内部类可能导致内存泄漏(隐式持有外部类引用),建议在 HandlerThread 中使用静态内部类 + WeakReference
  • 避免过度嵌套,影响可读性和维护性。

2. 集合框架

2.1 ArrayList vs LinkedList
特性ArrayListLinkedList
底层结构动态数组(连续内存)双向链表(分散内存)
随机访问O(1)O(n)
插入/删除(中间)O(n)O(1)
内存占用较小(仅元素开销)较大(每个节点含前后指针)
扩容机制扩容 1.5 倍,触发 Arrays.copyOf无固定容量,动态添加节点

选择建议

  • 频繁读取 → ArrayList
  • 频繁插入删除 → LinkedList
  • Android 中推荐 ArrayList,因缓存局部性更好,GC 更友好。
2.2 HashMap vs HashTable
特性HashMapHashTable
线程安全❌ 非线程安全✅ 方法加 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
特性synchronizedvolatile
原子性保证不保证
可见性保证保证
有序性保证(通过内存屏障)保证(禁止指令重排)
作用范围方法或代码块变量
性能开销高(阻塞、上下文切换)

使用建议

  • 保证原子性 + 可见性 → synchronizedReentrantLock
  • 仅需可见性 → volatile(如状态标志位)
3.3 线程池(ThreadPoolExecutor)
new ThreadPoolExecutor(
    corePoolSize,      // 核心线程数
    maximumPoolSize,   // 最大线程数
    keepAliveTime,     // 空闲线程存活时间
    unit,              // 时间单位
    workQueue,         // 任务队列(BlockingQueue)
    threadFactory,     // 线程工厂
    handler            // 拒绝策略
);

任务执行流程

  1. 任务提交 → 若当前线程 < corePoolSize → 创建新线程
  2. 否则 → 加入 workQueue
  3. 队列满 → 若线程 < maxPoolSize → 创建新线程
  4. 否则 → 触发拒绝策略(如抛出异常、丢弃任务等)

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)
        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 注册回调
val launcher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
    // 处理返回结果
}
launcher.launch("image/*")
1.2 Service
类型启动方式生命周期适用场景
Started ServicestartService()onCreate()onStartCommand()onDestroy()长时间后台任务(下载、播放)
Bound ServicebindService()onCreate()onBind()onUnbind()onDestroy()客户端-服务端通信
IntentServicestartService()基于 HandlerThread,任务完成自动停止串行执行后台任务(已废弃,推荐 WorkManager
前台服务startForegroundService()必须调用 startForeground()长期运行任务(音乐播放、定位)

注意:Android 9+ 需在 AndroidManifest.xml 中声明 FOREGROUND_SERVICE 权限。

1.3 BroadcastReceiver
注册方式优点缺点适用场景
静态注册应用未启动也可接收耗电、占用系统资源开机启动、网络状态变化
动态注册灵活、可控制生命周期需手动注销,否则内存泄漏活动期间监听事件

最佳实践

  • 动态注册必须在 onDestroy() 中调用 unregisterReceiver()
  • onReceive() 中禁止耗时操作(>10s 导致 ANR)
  • 使用 LocalBroadcastManager 实现应用内通信(AndroidX 已废弃,推荐 LiveDataFlow
1.4 ContentProvider

核心组件

  • URIcontent://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 与缓存机制

四级缓存

  1. Scrap:屏幕内临时移除的 ViewHolder(可快速复用)
  2. mCachedViews:最近移出屏幕的 ViewHolder(默认 2 个)
  3. ViewCacheExtension:开发者自定义缓存(极少使用)
  4. RecycledViewPool:被废弃的 ViewHolder 池(可跨 RecyclerView 共享)

性能优化

  • 使用 DiffUtil 计算最小更新集
  • 设置 setHasFixedSize(true) 若尺寸不变
  • 避免在 onBindViewHolder 中执行耗时操作

4. Handler 机制与内存泄漏

核心流程

Handler.send → MessageQueue.enqueue → Looper.loop → Handler.dispatch → handleMessage()

内存泄漏防护

  • 使用静态内部类 + WeakReference<Activity>
  • onDestroy() 中调用 handler.removeCallbacksAndMessages(null)
  • 使用 Lifecycle 感知组件(如 LifecycleCoroutineScope

三、性能优化(补充详细方案)

1. 内存优化

  • LeakCanary:自动检测内存泄漏
  • Bitmap 复用:使用 inBitmap(API 19+)
  • 对象池SparseArrayPools.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 推荐架构

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 协程:替代 AsyncTaskRxJava
  • 跨平台:Flutter(Dart)、React Native(JS)、KMM(Kotlin Multiplatform)

七、场景题与开放性问题(补充回答模板)

“请介绍最有挑战的项目”

使用 STAR 法则

  • Situation:项目背景
  • Task:你的职责
  • Action:采取的技术方案
  • Result:量化成果(性能提升 X%)

总结:本文覆盖 Android 开发全栈知识,建议结合源码(AOSP、Jetpack)、实战项目与持续学习,构建可落地的技术能力。

下一步建议

  • 将本文作为知识地图,逐项深入
  • 阅读官方文档与源码
  • 参与开源项目或技术社区