diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json
index 3f99c3b..35c3102 100644
--- a/.obsidian/workspace.json
+++ b/.obsidian/workspace.json
@@ -13,12 +13,12 @@
"state": {
"type": "markdown",
"state": {
- "file": "docs/adb调试命令/adb常用命令.md",
+ "file": "docs/cursor/cursor.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
- "title": "adb常用命令"
+ "title": "cursor"
}
}
]
@@ -185,41 +185,41 @@
},
"active": "9a5781991bf94030",
"lastOpenFiles": [
- "docs/cursor/cursor使用技巧.md",
- "docs/adb调试命令/linux常用命令.md",
- "docs/adb调试命令/常用linux命令.md",
- "docs/adb调试命令/adb常用命令.md",
- "docs/Obsidian笔记体系/Daily/2026-01-14.md",
- "docs/Obsidian笔记体系/Daily/2026-01-13.md",
- "docs/Obsidian笔记体系/Daily/2024-06-02.md",
- "docs/cursor/cursor.md",
- "docs/Obsidian/高频命令.md",
- "docs/Obsidian笔记体系/Projects/知你-调测/知你--调测.md",
- "docs/Obsidian笔记体系/Projects/saars开发/数据库配置.md",
- "docs/Obsidian笔记体系/Areas/03-Window系统/SurfaceFlinger交互流程.md",
- "docs/Obsidian笔记体系/Areas/03-Window系统/窗口类型与层级.md",
- "docs/Obsidian笔记体系/Areas/03-Window系统/触摸事件传递.md",
- "docs/dify/密码输入错误次数超过限制时的机制.md",
- "docs/dify/管理员账户.md",
- "docs/Obsidian/2026-01-05 个人文档管理.md",
- "未命名.base",
- "个人笔记体系.md",
- "使用说明.md",
- "docs/Obsidian笔记体系/README.md",
- "docs/gerrit/gerrit每日工作流程.md",
- "docs/Obsidian/资源网站.md",
- "docs/Obsidian/重要笔记.md",
- "docs/dify/作为安卓高级开发工程师,除了项目管理,你完全可以在技术专项、团队效能和个人成长三大领域构建更懂你的专属助手.md",
- "docs/dify/使用dify,可以生成一个专项事务助手吗,比如公司正规化事务助手.md",
- "docs/git/git常用命令.md",
- "docs/Obsidian笔记体系/Projects/知你-调测",
- "docs/gerrit",
- "gerrit",
- "更新部署脚本/deploy.sh",
- "更新部署脚本/deploy.py",
- "更新部署脚本/deploy.ps1",
- "更新部署脚本/deploy_config.json",
- "更新部署脚本",
- "新建文件夹"
+ "docs/Obsidian笔记体系/Daily/2026-01-15.md",
+ "docs/android面试/面试技巧/薪资谈判.md",
+ "docs/android面试/面试技巧/项目介绍.md",
+ "docs/android面试/面试技巧/常见问题.md",
+ "docs/android面试/面试技巧/自我介绍.md",
+ "docs/android面试/面试技巧",
+ "docs/android面试/项目经验/技术选型.md",
+ "docs/android面试/项目经验/团队协作经验.md",
+ "docs/android面试/项目经验/问题排查经验.md",
+ "docs/android面试/项目经验/性能优化实践.md",
+ "docs/android面试/项目经验/项目架构设计.md",
+ "docs/android面试/项目经验",
+ "docs/android面试/系统原理/系统启动流程.md",
+ "docs/android面试/系统原理/Zygote进程.md",
+ "docs/android面试/系统原理/进程与线程.md",
+ "docs/android面试/系统原理/内存管理.md",
+ "docs/android面试/系统原理/事件分发机制.md",
+ "docs/android面试/系统原理/View绘制流程.md",
+ "docs/android面试/系统原理/WMS原理.md",
+ "docs/android面试/系统原理/AMS原理.md",
+ "docs/android面试/系统原理/Binder机制.md",
+ "docs/android面试/系统原理",
+ "docs/android面试/开源框架/Jetpack组件.md",
+ "docs/android面试/开源框架/Dagger2原理.md",
+ "docs/android面试/开源框架/ButterKnife原理.md",
+ "docs/android面试/开源框架/EventBus原理.md",
+ "docs/android面试/开源框架/RxJava原理.md",
+ "docs/android面试/开源框架/Picasso原理.md",
+ "docs/android面试/开源框架/Glide原理.md",
+ "docs/android面试/开源框架",
+ "docs/android面试/算法与数据结构",
+ "docs/android面试/设计模式",
+ "docs/android面试/多线程与并发",
+ "docs/android面试/数据存储",
+ "docs/android面试/网络编程",
+ "docs/android面试/性能优化"
]
}
\ No newline at end of file
diff --git a/docs/Obsidian笔记体系/Daily/2026-01-15.md b/docs/Obsidian笔记体系/Daily/2026-01-15.md
new file mode 100644
index 0000000..30b39b7
--- /dev/null
+++ b/docs/Obsidian笔记体系/Daily/2026-01-15.md
@@ -0,0 +1,131 @@
+## 基本信息
+- **日期**: 2026-01-15
+- **星期**: 星期四
+- **天气**: 晴
+- **心情**: 良好
+
+## 今日计划
+
+### 工作安排
+- [ ] 知你--会员功能
+- [ ] 知你--聊天会话界面跑马灯温馨提示
+
+### 学习计划
+- [ ] 学习内容1
+- [ ] 学习内容2
+
+### 其他计划
+- [ ] 其他事项1
+
+## 工作记录
+
+### 已完成
+- ✅ 知你--会员功能开发
+ - 时间: HH:MM - HH:MM
+ - 内容: http://101.43.95.130:8082/c/zhini_im/+/106
+ - 收获:
+
+- ✅ 知你--聊天会话界面跑马灯温馨提示
+ - 时间: HH:MM - HH:MM
+ - 内容: http://101.43.95.130:8082/c/zhini_im/+/107
+ - 收获:
+### 进行中
+- 🔄 进行中事项1
+ - 开始时间: HH:MM
+ - 当前进度:
+ - 遇到的问题:
+ - 下一步计划:
+ - 继续知你--会员功能开发
+
+### 待处理
+- ⏳ 待处理事项1
+ - 计划时间: HH:MM
+ - 优先级: 高/中/低
+
+## 学习记录
+
+### 技术学习
+- **学习内容**:
+- **学习时间**: HH:MM - HH:MM
+- **学习方式**: 阅读/实践/视频
+- **关键收获**:
+- **相关链接**: [[相关文档]]
+
+### 源码阅读
+- **阅读模块**:
+- **阅读时间**: HH:MM - HH:MM
+- **关键理解**:
+- **疑问**:
+- **相关链接**: [[相关源码]]
+
+### 问题解决
+- **问题描述**:
+- **解决过程**:
+- **解决方案**:
+- **经验总结**:
+- **相关链接**: [[相关文档]]
+
+## 会议记录
+
+### 会议1
+- **时间**: HH:MM - HH:MM
+- **主题**:
+- **参与人**:
+- **关键内容**:
+- **行动项**:
+- **相关链接**: [[会议记录]]
+
+## 思考与总结
+
+### 今日收获
+1. 收获1
+2. 收获2
+3. 收获3
+
+### 今日反思
+- 做得好的地方:
+- 需要改进的地方:
+- 改进计划:
+
+### 明日计划
+1. 计划1
+2. 计划2
+3. 计划3
+
+## 技术笔记
+
+### 技术点1
+- **内容**:
+- **代码示例**:
+```java
+// 代码示例
+```
+
+- **关键理解**:
+- **相关链接**: [[相关文档]]
+
+### 技术点2
+- **内容**:
+- **关键理解**:
+
+## 问题与疑问
+
+### 问题1
+- **问题描述**:
+- **思考**:
+- **待解决**:
+
+### 问题2
+- **问题描述**:
+- **思考**:
+
+## 相关链接
+
+- [[相关项目]]
+- [[相关文档]]
+- [[相关笔记]]
+
+## 备注
+
+- 备注1
+- 备注2
diff --git a/docs/android面试/README.md b/docs/android面试/README.md
new file mode 100644
index 0000000..299f7a1
--- /dev/null
+++ b/docs/android面试/README.md
@@ -0,0 +1,164 @@
+# Android 面试知识体系
+
+## 目录结构
+
+- [基础知识](#基础知识)
+- [核心组件](#核心组件)
+- [系统架构](#系统架构)
+- [性能优化](#性能优化)
+- [网络编程](#网络编程)
+- [数据存储](#数据存储)
+- [多线程与并发](#多线程与并发)
+- [设计模式](#设计模式)
+- [算法与数据结构](#算法与数据结构)
+- [开源框架](#开源框架)
+- [系统原理](#系统原理)
+- [项目经验](#项目经验)
+- [面试技巧](#面试技巧)
+
+---
+
+## 基础知识
+
+- [Java基础](基础知识/Java基础.md)
+- [Kotlin基础](基础知识/Kotlin基础.md)
+- [Android基础](基础知识/Android基础.md)
+- [Android版本特性](基础知识/Android版本特性.md)
+
+---
+
+## 核心组件
+
+- [Activity详解](核心组件/Activity详解.md)
+- [Service详解](核心组件/Service详解.md)
+- [BroadcastReceiver详解](核心组件/BroadcastReceiver详解.md)
+- [ContentProvider详解](核心组件/ContentProvider详解.md)
+- [Fragment详解](核心组件/Fragment详解.md)
+- [Intent详解](核心组件/Intent详解.md)
+
+---
+
+## 系统架构
+
+- [MVC架构](系统架构/MVC架构.md)
+- [MVP架构](系统架构/MVP架构.md)
+- [MVVM架构](系统架构/MVVM架构.md)
+- [组件化架构](系统架构/组件化架构.md)
+- [模块化设计](系统架构/模块化设计.md)
+- [Clean Architecture](系统架构/Clean_Architecture.md)
+
+---
+
+## 性能优化
+
+- [启动优化](性能优化/启动优化.md)
+- [内存优化](性能优化/内存优化.md)
+- [布局优化](性能优化/布局优化.md)
+- [网络优化](性能优化/网络优化.md)
+- [电量优化](性能优化/电量优化.md)
+- [流畅度优化](性能优化/流畅度优化.md)
+
+---
+
+## 网络编程
+
+- [HTTP与HTTPS](网络编程/HTTP与HTTPS.md)
+- [OkHttp原理](网络编程/OkHttp原理.md)
+- [Retrofit原理](网络编程/Retrofit原理.md)
+- [WebSocket](网络编程/WebSocket.md)
+- [网络请求优化](网络编程/网络请求优化.md)
+
+---
+
+## 数据存储
+
+- [SharedPreferences](数据存储/SharedPreferences.md)
+- [SQLite数据库](数据存储/SQLite数据库.md)
+- [Room数据库](数据存储/Room数据库.md)
+- [文件存储](数据存储/文件存储.md)
+- [MMKV](数据存储/MMKV.md)
+
+---
+
+## 多线程与并发
+
+- [线程基础](多线程与并发/线程基础.md)
+- [线程池](多线程与并发/线程池.md)
+- [Handler机制](多线程与并发/Handler机制.md)
+- [AsyncTask](多线程与并发/AsyncTask.md)
+- [协程](多线程与并发/协程.md)
+- [并发编程](多线程与并发/并发编程.md)
+
+---
+
+## 设计模式
+
+- [单例模式](设计模式/单例模式.md)
+- [工厂模式](设计模式/工厂模式.md)
+- [观察者模式](设计模式/观察者模式.md)
+- [适配器模式](设计模式/适配器模式.md)
+- [建造者模式](设计模式/建造者模式.md)
+- [策略模式](设计模式/策略模式.md)
+- [代理模式](设计模式/代理模式.md)
+- [装饰者模式](设计模式/装饰者模式.md)
+
+---
+
+## 算法与数据结构
+
+- [数组与链表](算法与数据结构/数组与链表.md)
+- [栈与队列](算法与数据结构/栈与队列.md)
+- [树与二叉树](算法与数据结构/树与二叉树.md)
+- [排序算法](算法与数据结构/排序算法.md)
+- [查找算法](算法与数据结构/查找算法.md)
+- [动态规划](算法与数据结构/动态规划.md)
+- [字符串算法](算法与数据结构/字符串算法.md)
+
+---
+
+## 开源框架
+
+- [Glide原理](开源框架/Glide原理.md)
+- [Picasso原理](开源框架/Picasso原理.md)
+- [RxJava原理](开源框架/RxJava原理.md)
+- [EventBus原理](开源框架/EventBus原理.md)
+- [ButterKnife原理](开源框架/ButterKnife原理.md)
+- [Dagger2原理](开源框架/Dagger2原理.md)
+- [Jetpack组件](开源框架/Jetpack组件.md)
+
+---
+
+## 系统原理
+
+- [Binder机制](系统原理/Binder机制.md)
+- [AMS原理](系统原理/AMS原理.md)
+- [WMS原理](系统原理/WMS原理.md)
+- [View绘制流程](系统原理/View绘制流程.md)
+- [事件分发机制](系统原理/事件分发机制.md)
+- [内存管理](系统原理/内存管理.md)
+- [进程与线程](系统原理/进程与线程.md)
+- [Zygote进程](系统原理/Zygote进程.md)
+- [系统启动流程](系统原理/系统启动流程.md)
+
+---
+
+## 项目经验
+
+- [项目架构设计](项目经验/项目架构设计.md)
+- [性能优化实践](项目经验/性能优化实践.md)
+- [问题排查经验](项目经验/问题排查经验.md)
+- [团队协作经验](项目经验/团队协作经验.md)
+- [技术选型](项目经验/技术选型.md)
+
+---
+
+## 面试技巧
+
+- [自我介绍](面试技巧/自我介绍.md)
+- [常见问题](面试技巧/常见问题.md)
+- [项目介绍](面试技巧/项目介绍.md)
+- [薪资谈判](面试技巧/薪资谈判.md)
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/基础知识/Android基础.md b/docs/android面试/基础知识/Android基础.md
new file mode 100644
index 0000000..8680c00
--- /dev/null
+++ b/docs/android面试/基础知识/Android基础.md
@@ -0,0 +1,522 @@
+# Android基础
+
+## 目录
+- [Android系统架构](#android系统架构)
+- [应用组件](#应用组件)
+- [应用生命周期](#应用生命周期)
+- [资源管理](#资源管理)
+- [权限系统](#权限系统)
+- [应用签名](#应用签名)
+- [打包流程](#打包流程)
+- [版本适配](#版本适配)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Android系统架构
+
+### 四层架构
+
+```
+┌─────────────────────────────────┐
+│ Applications(应用层) │
+│ (系统应用、第三方应用) │
+└─────────────────────────────────┘
+ │
+┌─────────────────────────────────┐
+│ Application Framework(应用框架层)│
+│ (Activity Manager, Content Provider等)│
+└─────────────────────────────────┘
+ │
+┌─────────────────────────────────┐
+│ Libraries & Android Runtime │
+│ (系统库、Android运行时) │
+└─────────────────────────────────┘
+ │
+┌─────────────────────────────────┐
+│ Linux Kernel(Linux内核) │
+│ (驱动、内存管理、进程管理等) │
+└─────────────────────────────────┘
+```
+
+### 各层说明
+
+#### 1. 应用层(Applications)
+- 系统应用:电话、短信、浏览器等
+- 第三方应用:用户安装的应用
+
+#### 2. 应用框架层(Application Framework)
+- **Activity Manager**:管理 Activity 生命周期
+- **Window Manager**:管理窗口
+- **Content Provider**:数据共享
+- **View System**:UI 组件
+- **Package Manager**:应用管理
+- **Telephony Manager**:电话管理
+- **Resource Manager**:资源管理
+- **Location Manager**:位置管理
+- **Notification Manager**:通知管理
+
+#### 3. 系统库和运行时
+- **系统库**:SQLite、WebKit、OpenGL ES 等
+- **Android Runtime**:ART(Android 5.0+)或 Dalvik
+
+#### 4. Linux 内核
+- 驱动:显示驱动、音频驱动、相机驱动等
+- 内存管理、进程管理、网络协议栈
+
+---
+
+## 应用组件
+
+### 四大组件
+
+#### 1. Activity(活动)
+
+```java
+// Activity:用户界面
+public class MainActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+}
+```
+
+#### 2. Service(服务)
+
+```java
+// Service:后台服务
+public class MyService extends Service {
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
+```
+
+#### 3. BroadcastReceiver(广播接收器)
+
+```java
+// BroadcastReceiver:接收广播
+public class MyReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 处理广播
+ }
+}
+```
+
+#### 4. ContentProvider(内容提供者)
+
+```java
+// ContentProvider:数据共享
+public class MyProvider extends ContentProvider {
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ // 查询数据
+ return null;
+ }
+}
+```
+
+---
+
+## 应用生命周期
+
+### Application 生命周期
+
+```java
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ // 应用创建时调用
+ }
+
+ @Override
+ public void onTerminate() {
+ super.onTerminate();
+ // 应用终止时调用(通常不会调用)
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ // 内存不足时调用
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+ super.onTrimMemory(level);
+ // 内存紧张时调用
+ }
+}
+```
+
+### Activity 生命周期
+
+```java
+public class MainActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 创建 Activity
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ // Activity 可见但不可交互
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // Activity 可见且可交互
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ // Activity 失去焦点
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ // Activity 不可见
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ // Activity 被销毁
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onRestart();
+ // Activity 重新启动
+ }
+}
+```
+
+---
+
+## 资源管理
+
+### 资源类型
+
+```xml
+
+MyApp
+
+
+#3F51B5
+
+
+16dp
+
+
+...
+
+
+...
+```
+
+### 资源访问
+
+```java
+// 代码中访问资源
+String appName = getString(R.string.app_name);
+int color = getColor(R.color.primary);
+float padding = getResources().getDimension(R.dimen.padding);
+
+// XML 中访问资源
+android:text="@string/app_name"
+android:background="@color/primary"
+android:padding="@dimen/padding"
+```
+
+### 多语言支持
+
+```xml
+
+Hello
+
+
+你好
+
+
+Hello
+```
+
+---
+
+## 权限系统
+
+### 权限类型
+
+#### 1. 普通权限(Normal Permissions)
+
+```xml
+
+
+
+```
+
+#### 2. 危险权限(Dangerous Permissions)
+
+```java
+// Android 6.0+ 需要运行时申请
+if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.CAMERA},
+ REQUEST_CODE);
+}
+
+@Override
+public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ if (requestCode == REQUEST_CODE) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // 权限已授予
+ } else {
+ // 权限被拒绝
+ }
+ }
+}
+```
+
+### 权限组
+
+```java
+// 权限组
+// - CALENDAR:日历权限
+// - CAMERA:相机权限
+// - CONTACTS:联系人权限
+// - LOCATION:位置权限
+// - MICROPHONE:麦克风权限
+// - PHONE:电话权限
+// - SENSORS:传感器权限
+// - SMS:短信权限
+// - STORAGE:存储权限
+```
+
+---
+
+## 应用签名
+
+### 签名作用
+
+1. **身份标识**:标识应用开发者
+2. **完整性验证**:确保应用未被篡改
+3. **权限控制**:相同签名的应用可以共享数据
+
+### 签名流程
+
+```bash
+# 生成密钥库
+keytool -genkey -v -keystore my-release-key.jks
+ -keyalg RSA -keysize 2048 -validity 10000
+ -alias my-key-alias
+
+# 签名 APK
+jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
+ -keystore my-release-key.jks app-release-unsigned.apk my-key-alias
+
+# 验证签名
+jarsigner -verify -verbose -certs app-release-unsigned.apk
+```
+
+### Gradle 配置
+
+```gradle
+android {
+ signingConfigs {
+ release {
+ storeFile file('my-release-key.jks')
+ storePassword 'password'
+ keyAlias 'my-key-alias'
+ keyPassword 'password'
+ }
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.release
+ }
+ }
+}
+```
+
+---
+
+## 打包流程
+
+### APK 构建流程
+
+```
+1. 编译 Java/Kotlin 代码 → .class 文件
+2. 转换为 DEX 文件
+3. 打包资源文件
+4. 生成未签名 APK
+5. 签名 APK
+6. 对齐优化(zipalign)
+7. 生成最终 APK
+```
+
+### 构建工具
+
+```gradle
+// build.gradle
+android {
+ compileSdkVersion 30
+
+ defaultConfig {
+ applicationId "com.example.app"
+ minSdkVersion 21
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+```
+
+---
+
+## 版本适配
+
+### Target SDK 版本
+
+```gradle
+android {
+ defaultConfig {
+ targetSdkVersion 30 // 目标 SDK 版本
+ }
+}
+```
+
+### 版本适配要点
+
+#### Android 6.0 (API 23) - 运行时权限
+
+```java
+// 需要运行时申请危险权限
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ requestPermissions(...);
+}
+```
+
+#### Android 7.0 (API 24) - FileProvider
+
+```xml
+
+
+
+
+```
+
+#### Android 8.0 (API 26) - 通知渠道
+
+```java
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel = new NotificationChannel(
+ CHANNEL_ID, "Channel Name", NotificationManager.IMPORTANCE_DEFAULT);
+ notificationManager.createNotificationChannel(channel);
+}
+```
+
+#### Android 9.0 (API 28) - 网络安全
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+#### Android 10 (API 29) - 分区存储
+
+```java
+// 使用 MediaStore 访问文件
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ // 使用作用域存储
+}
+```
+
+#### Android 11 (API 30) - 包可见性
+
+```xml
+
+
+
+
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Android 系统架构?
+
+**答案:**
+四层架构:
+1. **应用层**:系统应用和第三方应用
+2. **应用框架层**:Activity Manager、Window Manager 等
+3. **系统库和运行时**:系统库、ART
+4. **Linux 内核**:驱动、内存管理、进程管理
+
+### Q2: 四大组件?
+
+**答案:**
+1. **Activity**:用户界面
+2. **Service**:后台服务
+3. **BroadcastReceiver**:广播接收器
+4. **ContentProvider**:内容提供者
+
+### Q3: Activity 生命周期?
+
+**答案:**
+onCreate → onStart → onResume → onPause → onStop → onDestroy
+onRestart(从 onStop 恢复时调用)
+
+### Q4: 权限系统?
+
+**答案:**
+- **普通权限**:安装时自动授予
+- **危险权限**:Android 6.0+ 需要运行时申请
+- **特殊权限**:需要特殊处理
+
+### Q5: 版本适配要点?
+
+**答案:**
+- Android 6.0:运行时权限
+- Android 7.0:FileProvider
+- Android 8.0:通知渠道
+- Android 9.0:网络安全
+- Android 10:分区存储
+- Android 11:包可见性
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/基础知识/Android版本特性.md b/docs/android面试/基础知识/Android版本特性.md
new file mode 100644
index 0000000..a7a8464
--- /dev/null
+++ b/docs/android面试/基础知识/Android版本特性.md
@@ -0,0 +1,14 @@
+# Android版本特性
+
+## 待补充内容
+
+- Android 5.0 (Lollipop)
+- Android 6.0 (Marshmallow)
+- Android 7.0 (Nougat)
+- Android 8.0 (Oreo)
+- Android 9.0 (Pie)
+- Android 10
+- Android 11
+- Android 12
+- Android 13
+- Android 14
diff --git a/docs/android面试/基础知识/Java基础.md b/docs/android面试/基础知识/Java基础.md
new file mode 100644
index 0000000..3ec4651
--- /dev/null
+++ b/docs/android面试/基础知识/Java基础.md
@@ -0,0 +1,543 @@
+# Java基础
+
+## 目录
+- [面向对象编程](#面向对象编程)
+- [集合框架](#集合框架)
+- [异常处理](#异常处理)
+- [泛型](#泛型)
+- [反射](#反射)
+- [注解](#注解)
+- [多线程基础](#多线程基础)
+- [IO流](#io流)
+- [JVM基础](#jvm基础)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 面向对象编程
+
+### 三大特性
+
+#### 1. 封装
+
+```java
+// 封装:隐藏内部实现,提供公共接口
+public class User {
+ private String name; // 私有属性
+ private int age;
+
+ // 公共方法访问私有属性
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+```
+
+#### 2. 继承
+
+```java
+// 继承:子类继承父类的属性和方法
+public class Animal {
+ protected String name;
+
+ public void eat() {
+ System.out.println("Animal is eating");
+ }
+}
+
+public class Dog extends Animal {
+ public void bark() {
+ System.out.println("Dog is barking");
+ }
+
+ @Override
+ public void eat() {
+ System.out.println("Dog is eating");
+ }
+}
+```
+
+#### 3. 多态
+
+```java
+// 多态:同一接口,不同实现
+Animal animal1 = new Dog();
+Animal animal2 = new Cat();
+animal1.eat(); // 调用 Dog 的 eat 方法
+animal2.eat(); // 调用 Cat 的 eat 方法
+```
+
+### 抽象类和接口
+
+```java
+// 抽象类:可以有抽象方法和具体方法
+public abstract class Animal {
+ public abstract void makeSound();
+
+ public void sleep() {
+ System.out.println("Animal is sleeping");
+ }
+}
+
+// 接口:只有抽象方法(Java 8+ 可以有默认方法)
+public interface Flyable {
+ void fly();
+
+ default void land() {
+ System.out.println("Landing");
+ }
+}
+```
+
+---
+
+## 集合框架
+
+### List
+
+```java
+// ArrayList:动态数组
+List list = new ArrayList<>();
+list.add("A");
+list.add("B");
+list.get(0); // "A"
+
+// LinkedList:双向链表
+List linkedList = new LinkedList<>();
+linkedList.add("A");
+linkedList.addFirst("B");
+```
+
+### Set
+
+```java
+// HashSet:无序,不重复
+Set set = new HashSet<>();
+set.add("A");
+set.add("B");
+set.add("A"); // 重复,不会添加
+
+// TreeSet:有序,不重复
+Set treeSet = new TreeSet<>();
+treeSet.add("C");
+treeSet.add("A");
+treeSet.add("B");
+// 输出:A, B, C
+```
+
+### Map
+
+```java
+// HashMap:键值对,无序
+Map map = new HashMap<>();
+map.put("A", 1);
+map.put("B", 2);
+map.get("A"); // 1
+
+// TreeMap:键值对,有序
+Map treeMap = new TreeMap<>();
+treeMap.put("C", 3);
+treeMap.put("A", 1);
+treeMap.put("B", 2);
+// 按键排序:A, B, C
+```
+
+### 集合遍历
+
+```java
+// for-each 循环
+for (String item : list) {
+ System.out.println(item);
+}
+
+// Iterator
+Iterator iterator = list.iterator();
+while (iterator.hasNext()) {
+ String item = iterator.next();
+ System.out.println(item);
+}
+
+// Stream API(Java 8+)
+list.stream()
+ .filter(s -> s.startsWith("A"))
+ .forEach(System.out::println);
+```
+
+---
+
+## 异常处理
+
+### 异常类型
+
+```java
+// Throwable
+// ├── Error(错误,不可恢复)
+// └── Exception(异常,可恢复)
+// ├── RuntimeException(运行时异常)
+// └── CheckedException(检查异常)
+
+// RuntimeException:不需要捕获
+int[] arr = new int[5];
+int value = arr[10]; // ArrayIndexOutOfBoundsException
+
+// CheckedException:必须捕获或声明
+try {
+ FileInputStream fis = new FileInputStream("file.txt");
+} catch (FileNotFoundException e) {
+ e.printStackTrace();
+}
+```
+
+### 异常处理
+
+```java
+// try-catch-finally
+try {
+ // 可能抛出异常的代码
+ int result = 10 / 0;
+} catch (ArithmeticException e) {
+ // 处理异常
+ System.out.println("除零错误");
+} catch (Exception e) {
+ // 处理其他异常
+ e.printStackTrace();
+} finally {
+ // 无论是否异常都会执行
+ System.out.println("清理资源");
+}
+
+// try-with-resources(Java 7+)
+try (FileInputStream fis = new FileInputStream("file.txt")) {
+ // 使用资源
+} catch (IOException e) {
+ e.printStackTrace();
+} // 自动关闭资源
+```
+
+### 自定义异常
+
+```java
+// 自定义异常
+public class CustomException extends Exception {
+ public CustomException(String message) {
+ super(message);
+ }
+}
+
+// 使用
+public void method() throws CustomException {
+ throw new CustomException("自定义异常");
+}
+```
+
+---
+
+## 泛型
+
+### 泛型类
+
+```java
+// 泛型类
+public class Box {
+ private T item;
+
+ public void setItem(T item) {
+ this.item = item;
+ }
+
+ public T getItem() {
+ return item;
+ }
+}
+
+// 使用
+Box stringBox = new Box<>();
+stringBox.setItem("Hello");
+String value = stringBox.getItem();
+```
+
+### 泛型方法
+
+```java
+// 泛型方法
+public T getValue(T value) {
+ return value;
+}
+
+// 使用
+String str = getValue("Hello");
+Integer num = getValue(123);
+```
+
+### 通配符
+
+```java
+// 上界通配符:? extends T
+List extends Number> list1; // 可以是 Number 及其子类
+
+// 下界通配符:? super T
+List super Integer> list2; // 可以是 Integer 及其父类
+
+// 无界通配符:?
+List> list3; // 可以是任何类型
+```
+
+---
+
+## 反射
+
+### 获取 Class 对象
+
+```java
+// 方式1:通过类名
+Class> clazz = String.class;
+
+// 方式2:通过对象
+String str = "Hello";
+Class> clazz2 = str.getClass();
+
+// 方式3:通过类名字符串
+Class> clazz3 = Class.forName("java.lang.String");
+```
+
+### 反射操作
+
+```java
+// 创建对象
+Class> clazz = User.class;
+User user = (User) clazz.newInstance();
+
+// 获取字段
+Field field = clazz.getDeclaredField("name");
+field.setAccessible(true);
+field.set(user, "John");
+
+// 获取方法
+Method method = clazz.getMethod("getName");
+String name = (String) method.invoke(user);
+
+// 获取构造函数
+Constructor> constructor = clazz.getConstructor(String.class);
+User user2 = (User) constructor.newInstance("John");
+```
+
+---
+
+## 注解
+
+### 内置注解
+
+```java
+// @Override:重写方法
+@Override
+public void method() { }
+
+// @Deprecated:已废弃
+@Deprecated
+public void oldMethod() { }
+
+// @SuppressWarnings:抑制警告
+@SuppressWarnings("unchecked")
+public void method() { }
+```
+
+### 自定义注解
+
+```java
+// 定义注解
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MyAnnotation {
+ String value() default "";
+ int count() default 0;
+}
+
+// 使用注解
+@MyAnnotation(value = "test", count = 5)
+public void method() { }
+
+// 读取注解
+Method method = MyClass.class.getMethod("method");
+MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
+String value = annotation.value();
+```
+
+---
+
+## 多线程基础
+
+### 创建线程
+
+```java
+// 方式1:继承 Thread
+public class MyThread extends Thread {
+ @Override
+ public void run() {
+ System.out.println("Thread running");
+ }
+}
+MyThread thread = new MyThread();
+thread.start();
+
+// 方式2:实现 Runnable
+public class MyRunnable implements Runnable {
+ @Override
+ public void run() {
+ System.out.println("Thread running");
+ }
+}
+Thread thread2 = new Thread(new MyRunnable());
+thread2.start();
+
+// 方式3:Lambda 表达式
+Thread thread3 = new Thread(() -> {
+ System.out.println("Thread running");
+});
+thread3.start();
+```
+
+### 线程同步
+
+```java
+// synchronized 关键字
+public class Counter {
+ private int count = 0;
+
+ public synchronized void increment() {
+ count++;
+ }
+}
+
+// Lock
+private Lock lock = new ReentrantLock();
+
+public void method() {
+ lock.lock();
+ try {
+ // 临界区代码
+ } finally {
+ lock.unlock();
+ }
+}
+```
+
+---
+
+## IO流
+
+### 字节流
+
+```java
+// FileInputStream / FileOutputStream
+try (FileInputStream fis = new FileInputStream("input.txt");
+ FileOutputStream fos = new FileOutputStream("output.txt")) {
+ int data;
+ while ((data = fis.read()) != -1) {
+ fos.write(data);
+ }
+}
+```
+
+### 字符流
+
+```java
+// FileReader / FileWriter
+try (FileReader fr = new FileReader("input.txt");
+ FileWriter fw = new FileWriter("output.txt")) {
+ int data;
+ while ((data = fr.read()) != -1) {
+ fw.write(data);
+ }
+}
+```
+
+### 缓冲流
+
+```java
+// BufferedInputStream / BufferedOutputStream
+try (BufferedInputStream bis = new BufferedInputStream(
+ new FileInputStream("input.txt"));
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream("output.txt"))) {
+ int data;
+ while ((data = bis.read()) != -1) {
+ bos.write(data);
+ }
+}
+```
+
+---
+
+## JVM基础
+
+### 内存区域
+
+```java
+// JVM 内存区域
+// 1. 程序计数器:当前执行指令的地址
+// 2. 虚拟机栈:方法执行时的栈帧
+// 3. 本地方法栈:Native 方法执行
+// 4. 堆:对象实例
+// 5. 方法区:类信息、常量、静态变量
+```
+
+### 垃圾回收
+
+```java
+// GC 算法
+// 1. 标记-清除
+// 2. 标记-复制
+// 3. 标记-整理
+// 4. 分代收集
+
+// GC 类型
+// - Minor GC:新生代回收
+// - Major GC:老年代回收
+// - Full GC:整个堆回收
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Java 三大特性?
+
+**答案:**
+1. **封装**:隐藏内部实现,提供公共接口
+2. **继承**:子类继承父类的属性和方法
+3. **多态**:同一接口,不同实现
+
+### Q2: ArrayList 和 LinkedList 的区别?
+
+**答案:**
+- **ArrayList**:基于数组,随机访问快,插入删除慢
+- **LinkedList**:基于链表,随机访问慢,插入删除快
+
+### Q3: HashMap 的实现原理?
+
+**答案:**
+- 基于数组和链表(Java 8+ 使用红黑树)
+- 通过 hashCode 计算数组索引
+- 解决冲突使用链表或红黑树
+
+### Q4: 异常处理的机制?
+
+**答案:**
+- **try-catch-finally**:捕获和处理异常
+- **throws**:声明可能抛出的异常
+- **throw**:抛出异常
+
+### Q5: 泛型的作用?
+
+**答案:**
+1. 类型安全:编译时检查类型
+2. 消除强制转换
+3. 提高代码可读性
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/基础知识/Kotlin基础.md b/docs/android面试/基础知识/Kotlin基础.md
new file mode 100644
index 0000000..d35b845
--- /dev/null
+++ b/docs/android面试/基础知识/Kotlin基础.md
@@ -0,0 +1,451 @@
+# Kotlin基础
+
+## 目录
+- [基本语法](#基本语法)
+- [空安全](#空安全)
+- [扩展函数](#扩展函数)
+- [数据类](#数据类)
+- [密封类](#密封类)
+- [协程基础](#协程基础)
+- [委托](#委托)
+- [高阶函数](#高阶函数)
+- [Lambda表达式](#lambda表达式)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 基本语法
+
+### 变量声明
+
+```kotlin
+// 可变变量
+var name: String = "John"
+name = "Jane"
+
+// 不可变变量
+val age: Int = 25
+// age = 26 // 编译错误
+
+// 类型推断
+var count = 10 // 自动推断为 Int
+var message = "Hello" // 自动推断为 String
+```
+
+### 函数定义
+
+```kotlin
+// 普通函数
+fun add(a: Int, b: Int): Int {
+ return a + b
+}
+
+// 单表达式函数
+fun multiply(a: Int, b: Int) = a * b
+
+// 默认参数
+fun greet(name: String = "Guest") {
+ println("Hello, $name")
+}
+
+// 命名参数
+greet(name = "John")
+```
+
+### 控制流
+
+```kotlin
+// if 表达式
+val max = if (a > b) a else b
+
+// when 表达式(类似 switch)
+when (x) {
+ 1 -> println("One")
+ 2 -> println("Two")
+ else -> println("Other")
+}
+
+// for 循环
+for (i in 1..10) {
+ println(i)
+}
+
+for (item in list) {
+ println(item)
+}
+
+// while 循环
+while (condition) {
+ // 代码
+}
+```
+
+---
+
+## 空安全
+
+### 可空类型
+
+```kotlin
+// 可空类型
+var name: String? = null
+name = "John"
+
+// 安全调用
+val length = name?.length // 如果 name 为 null,返回 null
+
+// Elvis 操作符
+val length2 = name?.length ?: 0 // 如果 name 为 null,返回 0
+
+// 非空断言
+val length3 = name!!.length // 如果 name 为 null,抛出异常
+```
+
+### 空安全操作
+
+```kotlin
+// 安全调用链
+val length = user?.address?.street?.length
+
+// let 函数
+name?.let {
+ println(it.length)
+}
+
+// 类型检查
+if (obj is String) {
+ println(obj.length) // 自动转换为 String
+}
+```
+
+---
+
+## 扩展函数
+
+### 扩展函数定义
+
+```kotlin
+// 为 String 添加扩展函数
+fun String.removeSpaces(): String {
+ return this.replace(" ", "")
+}
+
+// 使用
+val text = "Hello World"
+val result = text.removeSpaces() // "HelloWorld"
+
+// 为 View 添加扩展函数
+fun View.show() {
+ this.visibility = View.VISIBLE
+}
+
+fun View.hide() {
+ this.visibility = View.GONE
+}
+```
+
+### 扩展属性
+
+```kotlin
+// 扩展属性
+val String.lastChar: Char
+ get() = this[this.length - 1]
+
+// 使用
+val text = "Hello"
+val last = text.lastChar // 'o'
+```
+
+---
+
+## 数据类
+
+### 数据类定义
+
+```kotlin
+// 数据类:自动生成 equals、hashCode、toString、copy 等方法
+data class User(
+ val id: Int,
+ val name: String,
+ val email: String
+)
+
+// 使用
+val user = User(1, "John", "john@example.com")
+println(user) // User(id=1, name=John, email=john@example.com)
+
+// 复制
+val user2 = user.copy(name = "Jane")
+
+// 解构
+val (id, name, email) = user
+```
+
+### 数据类限制
+
+```kotlin
+// 数据类限制
+// 1. 主构造函数至少有一个参数
+// 2. 主构造函数参数必须标记为 val 或 var
+// 3. 数据类不能是抽象、开放、密封或内部类
+```
+
+---
+
+## 密封类
+
+### 密封类定义
+
+```kotlin
+// 密封类:限制子类只能在同一个文件中
+sealed class Result {
+ data class Success(val data: T) : Result()
+ data class Error(val message: String) : Result()
+ object Loading : Result()
+}
+
+// 使用
+fun handleResult(result: Result) {
+ when (result) {
+ is Result.Success -> println(result.data)
+ is Result.Error -> println(result.message)
+ is Result.Loading -> println("Loading...")
+ }
+}
+```
+
+---
+
+## 协程基础
+
+### 协程创建
+
+```kotlin
+// 启动协程
+GlobalScope.launch {
+ delay(1000)
+ println("Hello from coroutine")
+}
+
+// 使用 runBlocking
+runBlocking {
+ delay(1000)
+ println("Hello")
+}
+
+// 使用 CoroutineScope
+val scope = CoroutineScope(Dispatchers.Main)
+scope.launch {
+ delay(1000)
+ println("Hello")
+}
+```
+
+### 协程作用域
+
+```kotlin
+// CoroutineScope
+class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
+ override fun onDestroy() {
+ cancel() // 取消所有协程
+ super.onDestroy()
+ }
+}
+
+// viewModelScope(ViewModel)
+class MyViewModel : ViewModel() {
+ fun loadData() {
+ viewModelScope.launch {
+ // 协程代码
+ }
+ }
+}
+
+// lifecycleScope(LifecycleOwner)
+lifecycleScope.launch {
+ // 协程代码
+}
+```
+
+### 协程上下文
+
+```kotlin
+// Dispatchers
+launch(Dispatchers.Main) {
+ // 主线程
+}
+
+launch(Dispatchers.IO) {
+ // IO 线程
+}
+
+launch(Dispatchers.Default) {
+ // 默认线程池
+}
+```
+
+---
+
+## 委托
+
+### 类委托
+
+```kotlin
+// 类委托:将接口实现委托给另一个对象
+interface Base {
+ fun print()
+}
+
+class BaseImpl(val x: Int) : Base {
+ override fun print() {
+ println(x)
+ }
+}
+
+class Derived(b: Base) : Base by b
+
+// 使用
+val b = BaseImpl(10)
+val derived = Derived(b)
+derived.print() // 10
+```
+
+### 属性委托
+
+```kotlin
+// lazy 委托:延迟初始化
+val lazyValue: String by lazy {
+ println("Computed!")
+ "Hello"
+}
+
+// 使用
+println(lazyValue) // 第一次访问时计算
+println(lazyValue) // 直接返回缓存值
+
+// observable 委托:监听属性变化
+var name: String by Delegates.observable("Initial") { prop, old, new ->
+ println("$old -> $new")
+}
+```
+
+---
+
+## 高阶函数
+
+### 高阶函数定义
+
+```kotlin
+// 高阶函数:接受函数作为参数或返回函数
+fun operation(x: Int, y: Int, op: (Int, Int) -> Int): Int {
+ return op(x, y)
+}
+
+// 使用
+val result = operation(5, 3) { a, b -> a + b } // 8
+val result2 = operation(5, 3) { a, b -> a * b } // 15
+```
+
+### 常用高阶函数
+
+```kotlin
+val list = listOf(1, 2, 3, 4, 5)
+
+// map:转换
+val doubled = list.map { it * 2 } // [2, 4, 6, 8, 10]
+
+// filter:过滤
+val evens = list.filter { it % 2 == 0 } // [2, 4]
+
+// reduce:累积
+val sum = list.reduce { acc, i -> acc + i } // 15
+
+// forEach:遍历
+list.forEach { println(it) }
+```
+
+---
+
+## Lambda表达式
+
+### Lambda 语法
+
+```kotlin
+// Lambda 表达式
+val sum = { x: Int, y: Int -> x + y }
+println(sum(1, 2)) // 3
+
+// 简化语法
+val list = listOf(1, 2, 3)
+list.forEach { println(it) }
+
+// it:单个参数的隐式名称
+list.map { it * 2 }
+```
+
+### Lambda 与集合
+
+```kotlin
+val numbers = listOf(1, 2, 3, 4, 5)
+
+// map
+val squares = numbers.map { it * it } // [1, 4, 9, 16, 25]
+
+// filter
+val evens = numbers.filter { it % 2 == 0 } // [2, 4]
+
+// find
+val firstEven = numbers.find { it % 2 == 0 } // 2
+
+// any / all
+val hasEven = numbers.any { it % 2 == 0 } // true
+val allEven = numbers.all { it % 2 == 0 } // false
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Kotlin 和 Java 的区别?
+
+**答案:**
+1. **空安全**:Kotlin 有可空类型,编译时检查
+2. **简洁性**:Kotlin 代码更简洁
+3. **扩展函数**:可以为类添加新方法
+4. **数据类**:自动生成常用方法
+5. **协程**:轻量级线程
+
+### Q2: Kotlin 空安全机制?
+
+**答案:**
+- 可空类型:`String?` 表示可能为 null
+- 安全调用:`?.` 操作符
+- Elvis 操作符:`?:` 提供默认值
+- 非空断言:`!!` 强制非空
+
+### Q3: 扩展函数的作用?
+
+**答案:**
+- 为现有类添加新方法
+- 不修改原类代码
+- 提高代码复用性
+- 使代码更易读
+
+### Q4: 数据类的特点?
+
+**答案:**
+- 自动生成 `equals`、`hashCode`、`toString`、`copy` 方法
+- 支持解构声明
+- 简化数据模型定义
+
+### Q5: 协程的优势?
+
+**答案:**
+1. 轻量级:比线程更轻量
+2. 挂起恢复:可以挂起和恢复
+3. 结构化并发:自动管理生命周期
+4. 简化异步代码
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/多线程与并发/AsyncTask.md b/docs/android面试/多线程与并发/AsyncTask.md
new file mode 100644
index 0000000..e718496
--- /dev/null
+++ b/docs/android面试/多线程与并发/AsyncTask.md
@@ -0,0 +1,296 @@
+# AsyncTask
+
+## 目录
+- [AsyncTask原理](#asynctask原理)
+- [AsyncTask生命周期](#asynctask生命周期)
+- [AsyncTask执行流程](#asynctask执行流程)
+- [AsyncTask问题](#asynctask问题)
+- [AsyncTask替代方案](#asynctask替代方案)
+- [AsyncTask最佳实践](#asynctask最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## AsyncTask原理
+
+### AsyncTask 简介
+
+```java
+// AsyncTask:异步任务类
+// 在后台线程执行任务,在主线程更新 UI
+// 已废弃(Android 11+),推荐使用协程或 ExecutorService
+```
+
+### AsyncTask 结构
+
+```java
+public abstract class AsyncTask {
+ // Params:参数类型
+ // Progress:进度类型
+ // Result:结果类型
+
+ // 在后台线程执行
+ protected abstract Result doInBackground(Params... params);
+
+ // 在主线程执行(任务开始前)
+ protected void onPreExecute() { }
+
+ // 在主线程执行(进度更新)
+ protected void onProgressUpdate(Progress... values) { }
+
+ // 在主线程执行(任务完成后)
+ protected void onPostExecute(Result result) { }
+}
+```
+
+---
+
+## AsyncTask生命周期
+
+### 生命周期方法
+
+```java
+public class MyAsyncTask extends AsyncTask {
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ // 主线程:任务开始前
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+ // 后台线程:执行任务
+ for (int i = 0; i < 100; i++) {
+ publishProgress(i); // 更新进度
+ }
+ return "Result";
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... values) {
+ super.onProgressUpdate(values);
+ // 主线程:进度更新
+ int progress = values[0];
+ progressBar.setProgress(progress);
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ super.onPostExecute(result);
+ // 主线程:任务完成
+ textView.setText(result);
+ }
+
+ @Override
+ protected void onCancelled() {
+ super.onCancelled();
+ // 主线程:任务取消
+ }
+}
+```
+
+---
+
+## AsyncTask执行流程
+
+### 执行流程
+
+```
+1. execute() → 创建任务
+2. onPreExecute() → 主线程执行
+3. doInBackground() → 后台线程执行
+4. publishProgress() → 更新进度
+5. onProgressUpdate() → 主线程更新 UI
+6. onPostExecute() → 主线程执行(任务完成)
+```
+
+### 执行示例
+
+```java
+// 创建并执行
+MyAsyncTask task = new MyAsyncTask();
+task.execute("param1", "param2");
+
+// 取消任务
+task.cancel(true);
+```
+
+---
+
+## AsyncTask问题
+
+### 1. 内存泄漏
+
+```java
+// ❌ 问题:AsyncTask 持有 Activity 引用
+public class MainActivity extends AppCompatActivity {
+ private MyAsyncTask task;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ task = new MyAsyncTask();
+ task.execute();
+ }
+
+ // 如果 Activity 销毁,但 AsyncTask 还在执行
+ // Activity 无法被回收
+}
+```
+
+### 2. 配置变更问题
+
+```java
+// ❌ 问题:屏幕旋转时 Activity 重建
+// AsyncTask 持有旧 Activity 引用
+// 可能导致崩溃或内存泄漏
+```
+
+### 3. 串行执行
+
+```java
+// AsyncTask 默认串行执行
+// 多个 AsyncTask 按顺序执行
+// 可能影响性能
+```
+
+### 4. 已废弃
+
+```java
+// Android 11+ 已废弃 AsyncTask
+// 推荐使用协程或 ExecutorService
+```
+
+---
+
+## AsyncTask替代方案
+
+### 方案1:协程(推荐)
+
+```kotlin
+// 使用协程
+lifecycleScope.launch {
+ val result = withContext(Dispatchers.IO) {
+ // 后台执行
+ loadData()
+ }
+ // 主线程更新 UI
+ updateUI(result)
+}
+```
+
+### 方案2:ExecutorService
+
+```java
+// 使用线程池
+ExecutorService executor = Executors.newCachedThreadPool();
+executor.execute(() -> {
+ // 后台执行
+ String result = loadData();
+
+ // 主线程更新 UI
+ runOnUiThread(() -> {
+ updateUI(result);
+ });
+});
+```
+
+### 方案3:RxJava
+
+```java
+// 使用 RxJava
+Observable.fromCallable(() -> loadData())
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ updateUI(result);
+ });
+```
+
+---
+
+## AsyncTask最佳实践
+
+### 1. 使用静态内部类
+
+```java
+// ✅ 使用静态内部类避免内存泄漏
+private static class MyAsyncTask extends AsyncTask {
+ private WeakReference activity;
+
+ MyAsyncTask(MainActivity activity) {
+ this.activity = new WeakReference<>(activity);
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+ // 执行任务
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ MainActivity act = activity.get();
+ if (act != null && !act.isFinishing()) {
+ // 更新 UI
+ }
+ }
+}
+```
+
+### 2. 及时取消
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ if (task != null) {
+ task.cancel(true);
+ }
+}
+```
+
+### 3. 使用替代方案
+
+```java
+// 推荐使用协程或 ExecutorService
+// AsyncTask 已废弃
+```
+
+---
+
+## 面试常见问题
+
+### Q1: AsyncTask 的原理?
+
+**答案:**
+- 在后台线程执行任务(doInBackground)
+- 在主线程更新 UI(onPostExecute、onProgressUpdate)
+- 使用线程池执行任务
+
+### Q2: AsyncTask 的问题?
+
+**答案:**
+1. 内存泄漏:持有 Activity 引用
+2. 配置变更:屏幕旋转时可能出问题
+3. 串行执行:默认串行,可能影响性能
+4. 已废弃:Android 11+ 已废弃
+
+### Q3: AsyncTask 的替代方案?
+
+**答案:**
+1. **协程**:Kotlin 官方推荐
+2. **ExecutorService**:线程池
+3. **RxJava**:响应式编程
+
+### Q4: 如何避免 AsyncTask 内存泄漏?
+
+**答案:**
+1. 使用静态内部类
+2. 使用 WeakReference
+3. 及时取消任务
+4. 使用替代方案
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/多线程与并发/Handler机制.md b/docs/android面试/多线程与并发/Handler机制.md
new file mode 100644
index 0000000..56ffaf5
--- /dev/null
+++ b/docs/android面试/多线程与并发/Handler机制.md
@@ -0,0 +1,366 @@
+# Handler机制
+
+## 目录
+- [Handler原理](#handler原理)
+- [Looper机制](#looper机制)
+- [MessageQueue](#messagequeue)
+- [Message传递](#message传递)
+- [Handler内存泄漏](#handler内存泄漏)
+- [Handler最佳实践](#handler最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Handler原理
+
+### Handler 作用
+
+```java
+// Handler:用于线程间通信
+// 主线程 → 子线程:通过 Handler 发送消息
+// 子线程 → 主线程:通过 Handler 更新 UI
+```
+
+### Handler 架构
+
+```
+┌─────────┐
+│ Handler │ ←─── 发送和处理消息
+└────┬────┘
+ │
+┌────▼────┐
+│ Looper │ ←─── 消息循环
+└────┬────┘
+ │
+┌────▼────┐
+│MessageQueue│ ←─── 消息队列
+└────┬────┘
+ │
+┌────▼────┐
+│ Message │ ←─── 消息对象
+└─────────┘
+```
+
+---
+
+## Looper机制
+
+### Looper 作用
+
+```java
+// Looper:消息循环器
+// 从 MessageQueue 中取出消息,分发给 Handler 处理
+
+// 主线程 Looper
+Looper looper = Looper.getMainLooper();
+
+// 子线程 Looper
+class MyThread extends Thread {
+ @Override
+ public void run() {
+ Looper.prepare(); // 创建 Looper
+ Looper.loop(); // 开始循环
+ }
+}
+```
+
+### Looper 原理
+
+```java
+// Looper.prepare()
+public static void prepare() {
+ if (sThreadLocal.get() != null) {
+ throw new RuntimeException("Only one Looper may be created per thread");
+ }
+ sThreadLocal.set(new Looper());
+}
+
+// Looper.loop()
+public static void loop() {
+ Looper me = myLooper();
+ MessageQueue queue = me.mQueue;
+ for (;;) {
+ Message msg = queue.next(); // 阻塞等待消息
+ if (msg == null) {
+ return;
+ }
+ msg.target.dispatchMessage(msg); // 分发消息
+ msg.recycleUnchecked();
+ }
+}
+```
+
+---
+
+## MessageQueue
+
+### MessageQueue 原理
+
+```java
+// MessageQueue:消息队列
+// 使用单链表存储消息
+// 按时间排序,时间早的在前面
+
+// 消息入队
+boolean enqueueMessage(Message msg, long when) {
+ // 插入消息到队列
+ // 按时间排序
+}
+
+// 消息出队
+Message next() {
+ // 取出消息
+ // 如果队列为空,阻塞等待
+}
+```
+
+### 消息优先级
+
+```java
+// 消息按时间排序
+// when 值小的先执行
+
+// 立即执行
+handler.sendMessage(msg); // when = 0
+
+// 延迟执行
+handler.sendMessageDelayed(msg, 1000); // when = SystemClock.uptimeMillis() + 1000
+```
+
+---
+
+## Message传递
+
+### 发送消息
+
+```java
+// 方式1:sendMessage
+Message msg = Message.obtain();
+msg.what = 1;
+msg.obj = "Data";
+handler.sendMessage(msg);
+
+// 方式2:sendMessageDelayed
+handler.sendMessageDelayed(msg, 1000);
+
+// 方式3:post
+handler.post(new Runnable() {
+ @Override
+ public void run() {
+ // 执行代码
+ }
+});
+
+// 方式4:postDelayed
+handler.postDelayed(runnable, 1000);
+```
+
+### 处理消息
+
+```java
+// Handler 处理消息
+public class MyHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 1:
+ // 处理消息
+ String data = (String) msg.obj;
+ break;
+ }
+ }
+}
+
+// 或使用 Callback
+Handler handler = new Handler(new Handler.Callback() {
+ @Override
+ public boolean handleMessage(Message msg) {
+ // 处理消息
+ return true; // true 表示已处理,不再调用 handleMessage
+ }
+});
+```
+
+### 消息分发流程
+
+```java
+// dispatchMessage 流程
+public void dispatchMessage(Message msg) {
+ if (msg.callback != null) {
+ // 1. 优先执行 Runnable
+ handleCallback(msg);
+ } else {
+ if (mCallback != null) {
+ // 2. 执行 Callback
+ if (mCallback.handleMessage(msg)) {
+ return;
+ }
+ }
+ // 3. 执行 handleMessage
+ handleMessage(msg);
+ }
+}
+```
+
+---
+
+## Handler内存泄漏
+
+### 泄漏原因
+
+```java
+// ❌ 问题:Handler 持有 Activity 引用
+public class MainActivity extends AppCompatActivity {
+ private Handler handler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Handler 持有 Activity 的隐式引用
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // 如果 Activity 已销毁,但 Handler 还在处理消息
+ }
+ }, 10000);
+ }
+}
+```
+
+### 解决方案
+
+#### 方案1:静态内部类 + WeakReference
+
+```java
+// ✅ 解决方案1:静态内部类 + WeakReference
+public class MainActivity extends AppCompatActivity {
+ private static class MyHandler extends Handler {
+ private WeakReference mActivity;
+
+ MyHandler(MainActivity activity) {
+ mActivity = new WeakReference<>(activity);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ MainActivity activity = mActivity.get();
+ if (activity == null || activity.isFinishing()) {
+ return;
+ }
+ // 处理消息
+ }
+ }
+
+ private MyHandler handler;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ handler = new MyHandler(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ handler.removeCallbacksAndMessages(null);
+ }
+}
+```
+
+#### 方案2:使用主线程 Looper
+
+```java
+// ✅ 解决方案2:使用主线程 Looper
+Handler handler = new Handler(Looper.getMainLooper());
+```
+
+#### 方案3:及时移除消息
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ handler.removeCallbacksAndMessages(null);
+}
+```
+
+---
+
+## Handler最佳实践
+
+### 1. 避免内存泄漏
+
+```java
+// 使用静态内部类 + WeakReference
+// 或使用主线程 Looper
+```
+
+### 2. 及时移除消息
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ handler.removeCallbacksAndMessages(null);
+}
+```
+
+### 3. 使用 Message.obtain()
+
+```java
+// ✅ 推荐:复用 Message 对象
+Message msg = Message.obtain();
+
+// ❌ 不推荐:创建新对象
+Message msg = new Message();
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Handler 的原理?
+
+**答案:**
+Handler → Looper → MessageQueue → Message
+- Handler 发送消息到 MessageQueue
+- Looper 从 MessageQueue 取出消息
+- Handler 处理消息
+
+### Q2: Looper 的作用?
+
+**答案:**
+- 消息循环器
+- 从 MessageQueue 取出消息
+- 分发给 Handler 处理
+
+### Q3: Handler 为什么会导致内存泄漏?
+
+**答案:**
+- Handler 持有 Activity 的隐式引用
+- Message 持有 Handler 的引用
+- MessageQueue 持有 Message 的引用
+- 如果 Handler 还有未处理的消息,Activity 无法被回收
+
+### Q4: 如何避免 Handler 内存泄漏?
+
+**答案:**
+1. 使用静态内部类 + WeakReference
+2. 使用主线程 Looper
+3. 及时移除消息(onDestroy 中)
+
+### Q5: Handler、Looper、MessageQueue 的关系?
+
+**答案:**
+- **Handler**:发送和处理消息
+- **Looper**:消息循环,从 MessageQueue 取消息
+- **MessageQueue**:消息队列,存储消息
+- 一个线程只有一个 Looper,一个 Looper 只有一个 MessageQueue,可以有多个 Handler
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/多线程与并发/协程.md b/docs/android面试/多线程与并发/协程.md
new file mode 100644
index 0000000..7a8e9ac
--- /dev/null
+++ b/docs/android面试/多线程与并发/协程.md
@@ -0,0 +1,343 @@
+# 协程
+
+## 目录
+- [协程概念](#协程概念)
+- [协程与线程](#协程与线程)
+- [协程作用域](#协程作用域)
+- [协程上下文](#协程上下文)
+- [协程取消](#协程取消)
+- [协程异常处理](#协程异常处理)
+- [协程最佳实践](#协程最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 协程概念
+
+### 什么是协程?
+
+```kotlin
+// 协程:轻量级线程
+// 可以挂起和恢复
+// 比线程更轻量,开销更小
+
+// 创建协程
+GlobalScope.launch {
+ delay(1000) // 挂起1秒
+ println("Hello from coroutine")
+}
+```
+
+### 协程特点
+
+1. **轻量级**:比线程更轻量,可以创建大量协程
+2. **挂起恢复**:可以挂起和恢复执行
+3. **结构化并发**:自动管理生命周期
+4. **简化异步代码**:代码更简洁易读
+
+---
+
+## 协程与线程
+
+### 协程 vs 线程
+
+| 特性 | 协程 | 线程 |
+|------|------|------|
+| 创建开销 | 小 | 大 |
+| 数量 | 可以创建大量 | 受系统限制 |
+| 切换开销 | 小 | 大 |
+| 阻塞 | 挂起(不阻塞线程) | 阻塞线程 |
+| 适用场景 | 异步操作 | CPU 密集型任务 |
+
+### 协程优势
+
+```kotlin
+// 协程:挂起不阻塞线程
+suspend fun loadData() {
+ delay(1000) // 挂起,不阻塞线程
+ // 其他协程可以继续执行
+}
+
+// 线程:阻塞线程
+Thread.sleep(1000) // 阻塞线程
+```
+
+---
+
+## 协程作用域
+
+### 作用域类型
+
+#### 1. GlobalScope
+
+```kotlin
+// GlobalScope:全局作用域
+// 生命周期与应用一致
+GlobalScope.launch {
+ delay(1000)
+ println("Hello")
+}
+```
+
+#### 2. CoroutineScope
+
+```kotlin
+// CoroutineScope:自定义作用域
+val scope = CoroutineScope(Dispatchers.Main)
+scope.launch {
+ delay(1000)
+ println("Hello")
+}
+scope.cancel() // 取消所有协程
+```
+
+#### 3. lifecycleScope
+
+```kotlin
+// lifecycleScope:与 LifecycleOwner 绑定
+class MainActivity : AppCompatActivity() {
+ fun loadData() {
+ lifecycleScope.launch {
+ val data = withContext(Dispatchers.IO) {
+ loadDataFromNetwork()
+ }
+ updateUI(data)
+ }
+ }
+}
+```
+
+#### 4. viewModelScope
+
+```kotlin
+// viewModelScope:与 ViewModel 绑定
+class MyViewModel : ViewModel() {
+ fun loadData() {
+ viewModelScope.launch {
+ val data = loadDataFromNetwork()
+ // 处理数据
+ }
+ }
+}
+```
+
+---
+
+## 协程上下文
+
+### Dispatchers
+
+```kotlin
+// Dispatchers.Main:主线程
+launch(Dispatchers.Main) {
+ // 更新 UI
+}
+
+// Dispatchers.IO:IO 线程
+launch(Dispatchers.IO) {
+ // 网络请求、文件操作
+}
+
+// Dispatchers.Default:默认线程池
+launch(Dispatchers.Default) {
+ // CPU 密集型任务
+}
+
+// Dispatchers.Unconfined:不指定线程
+launch(Dispatchers.Unconfined) {
+ // 在调用线程执行
+}
+```
+
+### 切换上下文
+
+```kotlin
+// 切换上下文
+launch(Dispatchers.Main) {
+ val data = withContext(Dispatchers.IO) {
+ // 在 IO 线程执行
+ loadDataFromNetwork()
+ }
+ // 回到主线程
+ updateUI(data)
+}
+```
+
+---
+
+## 协程取消
+
+### 取消协程
+
+```kotlin
+// 取消协程
+val job = launch {
+ delay(10000)
+ println("Done")
+}
+job.cancel() // 取消协程
+
+// 检查是否取消
+launch {
+ while (isActive) {
+ // 执行任务
+ delay(100)
+ }
+}
+```
+
+### 取消检查
+
+```kotlin
+// 检查取消状态
+suspend fun doWork() {
+ for (i in 1..1000) {
+ ensureActive() // 检查是否取消
+ // 执行任务
+ }
+}
+```
+
+### 取消异常
+
+```kotlin
+// 取消时抛出 CancellationException
+try {
+ delay(10000)
+} catch (e: CancellationException) {
+ // 处理取消
+ throw e // 必须重新抛出
+}
+```
+
+---
+
+## 协程异常处理
+
+### try-catch
+
+```kotlin
+// 使用 try-catch
+launch {
+ try {
+ val data = loadData()
+ } catch (e: Exception) {
+ // 处理异常
+ }
+}
+```
+
+### CoroutineExceptionHandler
+
+```kotlin
+// 使用 CoroutineExceptionHandler
+val handler = CoroutineExceptionHandler { _, exception ->
+ Log.e("Coroutine", "Exception: $exception")
+}
+
+launch(handler) {
+ throw Exception("Error")
+}
+```
+
+### SupervisorJob
+
+```kotlin
+// SupervisorJob:子协程异常不影响其他协程
+val supervisor = SupervisorJob()
+val scope = CoroutineScope(Dispatchers.Main + supervisor)
+
+scope.launch {
+ // 子协程1
+}
+
+scope.launch {
+ // 子协程2:异常不影响子协程1
+ throw Exception("Error")
+}
+```
+
+---
+
+## 协程最佳实践
+
+### 1. 使用合适的作用域
+
+```kotlin
+// ✅ 推荐:使用 lifecycleScope 或 viewModelScope
+lifecycleScope.launch {
+ // 协程代码
+}
+
+// ❌ 不推荐:使用 GlobalScope
+GlobalScope.launch {
+ // 可能导致内存泄漏
+}
+```
+
+### 2. 及时取消协程
+
+```kotlin
+// 在 onDestroy 中取消
+override fun onDestroy() {
+ super.onDestroy()
+ job.cancel()
+}
+```
+
+### 3. 使用 suspend 函数
+
+```kotlin
+// ✅ 推荐:使用 suspend 函数
+suspend fun loadData(): String {
+ return withContext(Dispatchers.IO) {
+ // 网络请求
+ }
+}
+
+// ❌ 不推荐:在协程中直接使用回调
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是协程?
+
+**答案:**
+- 轻量级线程
+- 可以挂起和恢复
+- 比线程更轻量,开销更小
+- 简化异步代码
+
+### Q2: 协程和线程的区别?
+
+**答案:**
+- **协程**:轻量级,可以创建大量,挂起不阻塞线程
+- **线程**:重量级,受系统限制,阻塞线程
+
+### Q3: 协程作用域?
+
+**答案:**
+1. **GlobalScope**:全局作用域
+2. **CoroutineScope**:自定义作用域
+3. **lifecycleScope**:与 LifecycleOwner 绑定
+4. **viewModelScope**:与 ViewModel 绑定
+
+### Q4: 如何取消协程?
+
+**答案:**
+1. 调用 `job.cancel()`
+2. 检查 `isActive`
+3. 使用 `ensureActive()`
+
+### Q5: 协程异常处理?
+
+**答案:**
+1. 使用 try-catch
+2. 使用 CoroutineExceptionHandler
+3. 使用 SupervisorJob
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/多线程与并发/并发编程.md b/docs/android面试/多线程与并发/并发编程.md
new file mode 100644
index 0000000..eadf4e4
--- /dev/null
+++ b/docs/android面试/多线程与并发/并发编程.md
@@ -0,0 +1,343 @@
+# 并发编程
+
+## 目录
+- [并发概念](#并发概念)
+- [同步与异步](#同步与异步)
+- [锁机制](#锁机制)
+- [原子类](#原子类)
+- [并发集合](#并发集合)
+- [并发编程最佳实践](#并发编程最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 并发概念
+
+### 并发 vs 并行
+
+```java
+// 并发:同一时间段内多个任务交替执行
+// 单核 CPU:时间片轮转
+
+// 并行:同一时刻多个任务同时执行
+// 多核 CPU:真正同时执行
+```
+
+### 并发问题
+
+```java
+// 问题1:竞态条件
+private int count = 0;
+
+public void increment() {
+ count++; // 非原子操作
+ // 1. 读取 count
+ // 2. count + 1
+ // 3. 写入 count
+ // 多线程同时执行可能导致数据错误
+}
+
+// 问题2:可见性问题
+private boolean flag = false;
+
+// 线程1
+flag = true;
+
+// 线程2
+while (!flag) {
+ // 可能永远循环(可见性问题)
+}
+```
+
+---
+
+## 同步与异步
+
+### 同步
+
+```java
+// 同步:按顺序执行,等待结果
+public void syncMethod() {
+ String result = loadData(); // 等待加载完成
+ updateUI(result);
+}
+```
+
+### 异步
+
+```java
+// 异步:不等待结果,继续执行
+public void asyncMethod() {
+ loadDataAsync(new Callback() {
+ @Override
+ public void onResult(String result) {
+ updateUI(result);
+ }
+ });
+ // 继续执行其他代码
+}
+```
+
+---
+
+## 锁机制
+
+### synchronized
+
+```java
+// 同步方法
+public synchronized void method() {
+ // 临界区代码
+}
+
+// 同步代码块
+public void method() {
+ synchronized (this) {
+ // 临界区代码
+ }
+}
+
+// 同步静态方法
+public static synchronized void staticMethod() {
+ // 临界区代码
+}
+```
+
+### ReentrantLock
+
+```java
+// ReentrantLock:可重入锁
+private Lock lock = new ReentrantLock();
+
+public void method() {
+ lock.lock();
+ try {
+ // 临界区代码
+ } finally {
+ lock.unlock();
+ }
+}
+
+// 可中断锁
+lock.lockInterruptibly();
+try {
+ // 临界区代码
+} finally {
+ lock.unlock();
+}
+```
+
+### ReadWriteLock
+
+```java
+// ReadWriteLock:读写锁
+private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+private Lock readLock = readWriteLock.readLock();
+private Lock writeLock = readWriteLock.writeLock();
+
+// 读操作
+public String read() {
+ readLock.lock();
+ try {
+ return data;
+ } finally {
+ readLock.unlock();
+ }
+}
+
+// 写操作
+public void write(String value) {
+ writeLock.lock();
+ try {
+ data = value;
+ } finally {
+ writeLock.unlock();
+ }
+}
+```
+
+---
+
+## 原子类
+
+### AtomicInteger
+
+```java
+// AtomicInteger:原子整数
+private AtomicInteger count = new AtomicInteger(0);
+
+// 原子操作
+count.incrementAndGet(); // 原子递增
+count.getAndIncrement(); // 先获取再递增
+count.addAndGet(10); // 原子加法
+```
+
+### AtomicReference
+
+```java
+// AtomicReference:原子引用
+private AtomicReference ref = new AtomicReference<>("initial");
+
+// 原子更新
+ref.compareAndSet("initial", "new"); // CAS 操作
+```
+
+### CAS 操作
+
+```java
+// CAS:Compare And Swap
+// 比较并交换
+// 如果当前值等于期望值,则更新为新值
+
+// 实现
+public boolean compareAndSet(int expect, int update) {
+ if (value == expect) {
+ value = update;
+ return true;
+ }
+ return false;
+}
+```
+
+---
+
+## 并发集合
+
+### ConcurrentHashMap
+
+```java
+// ConcurrentHashMap:线程安全的 HashMap
+ConcurrentHashMap map = new ConcurrentHashMap<>();
+map.put("key", "value");
+String value = map.get("key");
+
+// 特点:
+// - 分段锁机制
+// - 支持并发读写
+// - 性能优于 Hashtable
+```
+
+### CopyOnWriteArrayList
+
+```java
+// CopyOnWriteArrayList:线程安全的 ArrayList
+CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
+list.add("item");
+String item = list.get(0);
+
+// 特点:
+// - 写时复制
+// - 读操作无锁
+// - 适合读多写少场景
+```
+
+### BlockingQueue
+
+```java
+// BlockingQueue:阻塞队列
+BlockingQueue queue = new LinkedBlockingQueue<>();
+
+// 生产者
+queue.put("item"); // 阻塞直到有空间
+
+// 消费者
+String item = queue.take(); // 阻塞直到有元素
+```
+
+---
+
+## 并发编程最佳实践
+
+### 1. 避免死锁
+
+```java
+// ❌ 问题:可能死锁
+synchronized (lock1) {
+ synchronized (lock2) {
+ // 代码
+ }
+}
+
+// 另一个线程
+synchronized (lock2) {
+ synchronized (lock1) {
+ // 代码
+ }
+}
+
+// ✅ 解决:按相同顺序获取锁
+synchronized (lock1) {
+ synchronized (lock2) {
+ // 代码
+ }
+}
+```
+
+### 2. 使用并发集合
+
+```java
+// ✅ 使用并发集合
+ConcurrentHashMap map = new ConcurrentHashMap<>();
+
+// ❌ 使用同步包装
+Map map = Collections.synchronizedMap(new HashMap<>());
+```
+
+### 3. 最小化锁范围
+
+```java
+// ✅ 最小化锁范围
+public void method() {
+ // 不需要同步的代码
+ synchronized (this) {
+ // 需要同步的代码
+ }
+ // 不需要同步的代码
+}
+
+// ❌ 扩大锁范围
+public synchronized void method() {
+ // 所有代码都在锁内
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 并发和并行的区别?
+
+**答案:**
+- **并发**:同一时间段内多个任务交替执行
+- **并行**:同一时刻多个任务同时执行
+
+### Q2: 并发问题有哪些?
+
+**答案:**
+1. **竞态条件**:多线程同时修改共享数据
+2. **可见性问题**:线程修改数据其他线程看不到
+3. **死锁**:多个线程互相等待
+
+### Q3: synchronized 和 Lock 的区别?
+
+**答案:**
+- **synchronized**:JVM 层面,自动释放锁
+- **Lock**:API 层面,手动释放锁,更灵活
+
+### Q4: CAS 操作?
+
+**答案:**
+- Compare And Swap:比较并交换
+- 原子操作,无锁编程
+- 如果当前值等于期望值,则更新
+
+### Q5: 并发集合有哪些?
+
+**答案:**
+1. ConcurrentHashMap:线程安全的 HashMap
+2. CopyOnWriteArrayList:线程安全的 ArrayList
+3. BlockingQueue:阻塞队列
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/多线程与并发/线程基础.md b/docs/android面试/多线程与并发/线程基础.md
new file mode 100644
index 0000000..564746a
--- /dev/null
+++ b/docs/android面试/多线程与并发/线程基础.md
@@ -0,0 +1,345 @@
+# 线程基础
+
+## 目录
+- [线程概念](#线程概念)
+- [线程创建](#线程创建)
+- [线程状态](#线程状态)
+- [线程同步](#线程同步)
+- [线程通信](#线程通信)
+- [线程安全](#线程安全)
+- [线程基础最佳实践](#线程基础最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 线程概念
+
+### 进程 vs 线程
+
+```java
+// 进程:程序执行的基本单位
+// - 有独立的内存空间
+// - 进程间通信复杂
+
+// 线程:CPU 调度的基本单位
+// - 共享进程的内存空间
+// - 线程间通信简单
+```
+
+### 主线程 vs 子线程
+
+```java
+// 主线程(UI 线程)
+// - 负责 UI 更新
+// - 不能执行耗时操作
+// - 阻塞会导致 ANR
+
+// 子线程(工作线程)
+// - 执行耗时操作
+// - 不能直接更新 UI
+// - 需要通过 Handler 更新 UI
+```
+
+---
+
+## 线程创建
+
+### 方式1:继承 Thread
+
+```java
+public class MyThread extends Thread {
+ @Override
+ public void run() {
+ // 线程执行代码
+ System.out.println("Thread running");
+ }
+}
+
+// 使用
+MyThread thread = new MyThread();
+thread.start();
+```
+
+### 方式2:实现 Runnable
+
+```java
+public class MyRunnable implements Runnable {
+ @Override
+ public void run() {
+ // 线程执行代码
+ System.out.println("Thread running");
+ }
+}
+
+// 使用
+Thread thread = new Thread(new MyRunnable());
+thread.start();
+```
+
+### 方式3:Lambda 表达式
+
+```java
+Thread thread = new Thread(() -> {
+ System.out.println("Thread running");
+});
+thread.start();
+```
+
+---
+
+## 线程状态
+
+### 线程状态转换
+
+```
+NEW → RUNNABLE → BLOCKED → WAITING → TIMED_WAITING → TERMINATED
+```
+
+### 状态说明
+
+```java
+// NEW:新建状态
+Thread thread = new Thread();
+
+// RUNNABLE:可运行状态
+thread.start();
+
+// BLOCKED:阻塞状态(等待锁)
+synchronized (lock) {
+ // 其他线程等待锁
+}
+
+// WAITING:等待状态
+thread.wait();
+LockSupport.park();
+
+// TIMED_WAITING:超时等待
+Thread.sleep(1000);
+thread.wait(1000);
+
+// TERMINATED:终止状态
+// 线程执行完毕
+```
+
+---
+
+## 线程同步
+
+### synchronized
+
+```java
+// 同步方法
+public synchronized void method() {
+ // 临界区代码
+}
+
+// 同步代码块
+public void method() {
+ synchronized (this) {
+ // 临界区代码
+ }
+}
+
+// 同步静态方法
+public static synchronized void staticMethod() {
+ // 临界区代码
+}
+```
+
+### Lock
+
+```java
+// ReentrantLock
+private Lock lock = new ReentrantLock();
+
+public void method() {
+ lock.lock();
+ try {
+ // 临界区代码
+ } finally {
+ lock.unlock();
+ }
+}
+
+// ReadWriteLock
+private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+private Lock readLock = readWriteLock.readLock();
+private Lock writeLock = readWriteLock.writeLock();
+```
+
+### volatile
+
+```java
+// volatile:保证可见性,不保证原子性
+private volatile boolean flag = false;
+
+// 适用场景
+// 1. 状态标志
+// 2. 双重检查锁定
+```
+
+---
+
+## 线程通信
+
+### wait/notify
+
+```java
+// wait:等待
+synchronized (lock) {
+ while (!condition) {
+ lock.wait(); // 释放锁,等待通知
+ }
+}
+
+// notify:通知
+synchronized (lock) {
+ condition = true;
+ lock.notify(); // 唤醒一个等待线程
+ // lock.notifyAll(); // 唤醒所有等待线程
+}
+```
+
+### CountDownLatch
+
+```java
+// CountDownLatch:等待多个线程完成
+CountDownLatch latch = new CountDownLatch(3);
+
+// 线程中
+latch.countDown();
+
+// 主线程等待
+latch.await();
+```
+
+### CyclicBarrier
+
+```java
+// CyclicBarrier:多个线程等待到齐
+CyclicBarrier barrier = new CyclicBarrier(3);
+
+// 线程中
+barrier.await();
+```
+
+---
+
+## 线程安全
+
+### 线程安全问题
+
+```java
+// ❌ 问题:非线程安全
+private int count = 0;
+
+public void increment() {
+ count++; // 非原子操作
+}
+
+// ✅ 解决:使用同步
+private int count = 0;
+
+public synchronized void increment() {
+ count++;
+}
+```
+
+### 线程安全集合
+
+```java
+// ConcurrentHashMap:线程安全的 HashMap
+ConcurrentHashMap map = new ConcurrentHashMap<>();
+
+// CopyOnWriteArrayList:线程安全的 ArrayList
+CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
+
+// BlockingQueue:阻塞队列
+BlockingQueue queue = new LinkedBlockingQueue<>();
+```
+
+---
+
+## 线程基础最佳实践
+
+### 1. 避免在 UI 线程执行耗时操作
+
+```java
+// ❌ 错误
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ loadDataFromNetwork(); // 阻塞 UI 线程
+}
+
+// ✅ 正确
+new Thread(() -> {
+ loadDataFromNetwork();
+ runOnUiThread(() -> {
+ updateUI();
+ });
+}).start();
+```
+
+### 2. 使用线程池
+
+```java
+// 使用线程池管理线程
+ExecutorService executor = Executors.newCachedThreadPool();
+executor.execute(() -> {
+ // 执行任务
+});
+```
+
+### 3. 及时释放资源
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ // 停止线程
+ if (thread != null) {
+ thread.interrupt();
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 线程和进程的区别?
+
+**答案:**
+- **进程**:程序执行的基本单位,有独立内存空间
+- **线程**:CPU 调度的基本单位,共享进程内存空间
+
+### Q2: 如何创建线程?
+
+**答案:**
+1. 继承 Thread
+2. 实现 Runnable
+3. 使用 Lambda 表达式
+
+### Q3: 线程状态?
+
+**答案:**
+NEW → RUNNABLE → BLOCKED → WAITING → TIMED_WAITING → TERMINATED
+
+### Q4: 线程同步方式?
+
+**答案:**
+1. synchronized
+2. Lock
+3. volatile
+4. 原子类
+
+### Q5: wait 和 sleep 的区别?
+
+**答案:**
+- **wait**:释放锁,需要 notify 唤醒
+- **sleep**:不释放锁,时间到自动唤醒
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/多线程与并发/线程池.md b/docs/android面试/多线程与并发/线程池.md
new file mode 100644
index 0000000..0f40c6c
--- /dev/null
+++ b/docs/android面试/多线程与并发/线程池.md
@@ -0,0 +1,364 @@
+# 线程池
+
+## 目录
+- [线程池原理](#线程池原理)
+- [线程池类型](#线程池类型)
+- [线程池参数](#线程池参数)
+- [线程池执行流程](#线程池执行流程)
+- [线程池监控](#线程池监控)
+- [线程池最佳实践](#线程池最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 线程池原理
+
+### 为什么使用线程池?
+
+```java
+// ❌ 问题:频繁创建线程
+for (int i = 0; i < 100; i++) {
+ new Thread(() -> {
+ // 执行任务
+ }).start(); // 创建和销毁线程开销大
+}
+
+// ✅ 解决:使用线程池
+ExecutorService executor = Executors.newCachedThreadPool();
+for (int i = 0; i < 100; i++) {
+ executor.execute(() -> {
+ // 执行任务
+ });
+}
+```
+
+### 线程池优势
+
+1. **降低资源消耗**:复用线程,减少创建和销毁开销
+2. **提高响应速度**:任务到达时直接执行
+3. **提高线程可管理性**:统一管理线程
+4. **控制并发数**:限制同时执行的线程数
+
+---
+
+## 线程池类型
+
+### 1. FixedThreadPool
+
+```java
+// 固定大小的线程池
+ExecutorService executor = Executors.newFixedThreadPool(5);
+
+// 特点:
+// - 核心线程数 = 最大线程数 = 5
+// - 无界队列
+// - 适合执行长期任务
+```
+
+### 2. CachedThreadPool
+
+```java
+// 缓存线程池
+ExecutorService executor = Executors.newCachedThreadPool();
+
+// 特点:
+// - 核心线程数 = 0
+// - 最大线程数 = Integer.MAX_VALUE
+// - 适合执行短期任务
+```
+
+### 3. SingleThreadExecutor
+
+```java
+// 单线程线程池
+ExecutorService executor = Executors.newSingleThreadExecutor();
+
+// 特点:
+// - 核心线程数 = 最大线程数 = 1
+// - 无界队列
+// - 任务按顺序执行
+```
+
+### 4. ScheduledThreadPool
+
+```java
+// 定时任务线程池
+ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
+
+// 延迟执行
+executor.schedule(() -> {
+ // 执行任务
+}, 1, TimeUnit.SECONDS);
+
+// 周期性执行
+executor.scheduleAtFixedRate(() -> {
+ // 执行任务
+}, 0, 1, TimeUnit.SECONDS);
+```
+
+---
+
+## 线程池参数
+
+### ThreadPoolExecutor 参数
+
+```java
+ThreadPoolExecutor executor = new ThreadPoolExecutor(
+ corePoolSize, // 核心线程数
+ maximumPoolSize, // 最大线程数
+ keepAliveTime, // 空闲线程存活时间
+ unit, // 时间单位
+ workQueue, // 工作队列
+ threadFactory, // 线程工厂
+ handler // 拒绝策略
+);
+```
+
+### 参数说明
+
+#### 1. corePoolSize(核心线程数)
+
+```java
+// 核心线程数:即使空闲也保留的线程数
+int corePoolSize = 5;
+```
+
+#### 2. maximumPoolSize(最大线程数)
+
+```java
+// 最大线程数:允许的最大线程数
+int maximumPoolSize = 10;
+```
+
+#### 3. keepAliveTime(空闲线程存活时间)
+
+```java
+// 空闲线程存活时间:超过核心线程数的线程空闲多久后回收
+long keepAliveTime = 60L;
+TimeUnit unit = TimeUnit.SECONDS;
+```
+
+#### 4. workQueue(工作队列)
+
+```java
+// 工作队列类型
+BlockingQueue workQueue;
+
+// ArrayBlockingQueue:有界队列
+workQueue = new ArrayBlockingQueue<>(100);
+
+// LinkedBlockingQueue:无界队列
+workQueue = new LinkedBlockingQueue<>();
+
+// SynchronousQueue:同步队列
+workQueue = new SynchronousQueue<>();
+```
+
+#### 5. threadFactory(线程工厂)
+
+```java
+// 自定义线程工厂
+ThreadFactory threadFactory = new ThreadFactory() {
+ private int count = 0;
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r);
+ thread.setName("MyThread-" + count++);
+ return thread;
+ }
+};
+```
+
+#### 6. handler(拒绝策略)
+
+```java
+// 拒绝策略类型
+RejectedExecutionHandler handler;
+
+// AbortPolicy:抛出异常(默认)
+handler = new ThreadPoolExecutor.AbortPolicy();
+
+// CallerRunsPolicy:调用者执行
+handler = new ThreadPoolExecutor.CallerRunsPolicy();
+
+// DiscardPolicy:丢弃任务
+handler = new ThreadPoolExecutor.DiscardPolicy();
+
+// DiscardOldestPolicy:丢弃最老任务
+handler = new ThreadPoolExecutor.DiscardOldestPolicy();
+```
+
+---
+
+## 线程池执行流程
+
+### 执行流程
+
+```
+1. 提交任务
+2. 如果线程数 < corePoolSize,创建核心线程执行
+3. 如果线程数 >= corePoolSize,将任务加入队列
+4. 如果队列已满且线程数 < maximumPoolSize,创建新线程执行
+5. 如果队列已满且线程数 >= maximumPoolSize,执行拒绝策略
+```
+
+### 流程图
+
+```
+任务提交
+ ↓
+线程数 < corePoolSize?
+ ├─ 是 → 创建核心线程执行
+ └─ 否 → 队列未满?
+ ├─ 是 → 加入队列
+ └─ 否 → 线程数 < maximumPoolSize?
+ ├─ 是 → 创建线程执行
+ └─ 否 → 执行拒绝策略
+```
+
+---
+
+## 线程池监控
+
+### 监控指标
+
+```java
+ThreadPoolExecutor executor = ...;
+
+// 当前线程数
+int poolSize = executor.getPoolSize();
+
+// 活跃线程数
+int activeCount = executor.getActiveCount();
+
+// 已完成任务数
+long completedTaskCount = executor.getCompletedTaskCount();
+
+// 总任务数
+long taskCount = executor.getTaskCount();
+
+// 队列大小
+int queueSize = executor.getQueue().size();
+```
+
+### 自定义监控
+
+```java
+public class MonitoredThreadPoolExecutor extends ThreadPoolExecutor {
+ @Override
+ protected void beforeExecute(Thread t, Runnable r) {
+ super.beforeExecute(t, r);
+ // 任务执行前
+ Log.d("ThreadPool", "Task started: " + r);
+ }
+
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+ // 任务执行后
+ Log.d("ThreadPool", "Task completed: " + r);
+ }
+
+ @Override
+ protected void terminated() {
+ super.terminated();
+ // 线程池终止
+ Log.d("ThreadPool", "ThreadPool terminated");
+ }
+}
+```
+
+---
+
+## 线程池最佳实践
+
+### 1. 合理设置参数
+
+```java
+// ✅ 好的配置
+int corePoolSize = Runtime.getRuntime().availableProcessors();
+int maximumPoolSize = corePoolSize * 2;
+ThreadPoolExecutor executor = new ThreadPoolExecutor(
+ corePoolSize,
+ maximumPoolSize,
+ 60L,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(100),
+ new ThreadPoolExecutor.CallerRunsPolicy()
+);
+
+// ❌ 不好的配置
+ExecutorService executor = Executors.newCachedThreadPool();
+// 可能创建过多线程
+```
+
+### 2. 使用有界队列
+
+```java
+// ✅ 使用有界队列
+BlockingQueue queue = new ArrayBlockingQueue<>(100);
+
+// ❌ 使用无界队列可能导致内存溢出
+BlockingQueue queue = new LinkedBlockingQueue<>();
+```
+
+### 3. 设置拒绝策略
+
+```java
+// 设置合适的拒绝策略
+executor.setRejectedExecutionHandler(
+ new ThreadPoolExecutor.CallerRunsPolicy()
+);
+```
+
+### 4. 及时关闭线程池
+
+```java
+// 关闭线程池
+executor.shutdown(); // 等待任务完成
+// 或
+executor.shutdownNow(); // 立即关闭
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 为什么使用线程池?
+
+**答案:**
+1. 降低资源消耗:复用线程
+2. 提高响应速度:任务到达直接执行
+3. 提高线程可管理性:统一管理
+4. 控制并发数:限制线程数
+
+### Q2: 线程池的参数?
+
+**答案:**
+1. corePoolSize:核心线程数
+2. maximumPoolSize:最大线程数
+3. keepAliveTime:空闲线程存活时间
+4. workQueue:工作队列
+5. threadFactory:线程工厂
+6. handler:拒绝策略
+
+### Q3: 线程池执行流程?
+
+**答案:**
+1. 线程数 < corePoolSize:创建核心线程
+2. 线程数 >= corePoolSize:加入队列
+3. 队列满且线程数 < maximumPoolSize:创建新线程
+4. 队列满且线程数 >= maximumPoolSize:执行拒绝策略
+
+### Q4: 拒绝策略有哪些?
+
+**答案:**
+1. AbortPolicy:抛出异常
+2. CallerRunsPolicy:调用者执行
+3. DiscardPolicy:丢弃任务
+4. DiscardOldestPolicy:丢弃最老任务
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/ButterKnife原理.md b/docs/android面试/开源框架/ButterKnife原理.md
new file mode 100644
index 0000000..98103bd
--- /dev/null
+++ b/docs/android面试/开源框架/ButterKnife原理.md
@@ -0,0 +1,153 @@
+# ButterKnife原理
+
+## 目录
+- [ButterKnife原理](#butterknife原理)
+- [注解处理](#注解处理)
+- [代码生成](#代码生成)
+- [ButterKnife源码分析](#butterknife源码分析)
+- [ButterKnife最佳实践](#butterknife最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## ButterKnife原理
+
+### 定义
+
+```java
+// ButterKnife:视图绑定库
+// 使用注解减少 findViewById
+// 编译时生成代码
+```
+
+### 使用方式
+
+```java
+public class MainActivity extends AppCompatActivity {
+ @BindView(R.id.textView)
+ TextView textView;
+
+ @OnClick(R.id.button)
+ void onButtonClick() {
+ // 处理点击
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ ButterKnife.bind(this);
+ }
+}
+```
+
+---
+
+## 注解处理
+
+### 注解类型
+
+```java
+// @BindView:绑定 View
+@BindView(R.id.textView)
+TextView textView;
+
+// @OnClick:点击事件
+@OnClick(R.id.button)
+void onButtonClick() {}
+
+// @BindViews:绑定多个 View
+@BindViews({R.id.view1, R.id.view2})
+List views;
+```
+
+### 编译时处理
+
+```java
+// 编译时,注解处理器扫描注解
+// 生成绑定代码
+// 运行时调用生成的代码
+```
+
+---
+
+## 代码生成
+
+### 生成的代码
+
+```java
+// 编译时生成 MainActivity_ViewBinding
+public class MainActivity_ViewBinding implements Unbinder {
+ private MainActivity target;
+
+ public MainActivity_ViewBinding(MainActivity target, View source) {
+ this.target = target;
+ target.textView = source.findViewById(R.id.textView);
+ }
+}
+```
+
+---
+
+## ButterKnife源码分析
+
+### 关键类
+
+```java
+// ButterKnife:入口类
+// ViewBinding:视图绑定
+// Unbinder:解绑接口
+```
+
+---
+
+## ButterKnife最佳实践
+
+### 1. 及时解绑
+
+```java
+private Unbinder unbinder;
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ unbinder = ButterKnife.bind(this);
+}
+
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ if (unbinder != null) {
+ unbinder.unbind();
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: ButterKnife 的原理?
+
+**答案:**
+- 使用注解标记 View
+- 编译时生成绑定代码
+- 运行时调用生成的代码
+
+### Q2: ButterKnife 的优缺点?
+
+**答案:**
+- **优点**:减少 findViewById,代码简洁
+- **缺点**:需要编译时处理,已停止维护
+
+### Q3: ButterKnife 的替代方案?
+
+**答案:**
+- ViewBinding(官方推荐)
+- DataBinding
+- Kotlin 扩展
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/Dagger2原理.md b/docs/android面试/开源框架/Dagger2原理.md
new file mode 100644
index 0000000..c7cdc5a
--- /dev/null
+++ b/docs/android面试/开源框架/Dagger2原理.md
@@ -0,0 +1,195 @@
+# Dagger2原理
+
+## 目录
+- [Dagger2原理](#dagger2原理)
+- [依赖注入](#依赖注入)
+- [注解处理](#注解处理)
+- [组件与模块](#组件与模块)
+- [Dagger2源码分析](#dagger2源码分析)
+- [Dagger2最佳实践](#dagger2最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Dagger2原理
+
+### 定义
+
+```java
+// Dagger2:依赖注入框架
+// 编译时生成代码
+// 类型安全
+// 性能好
+```
+
+### 核心概念
+
+```java
+// 1. Component:组件,注入器
+// 2. Module:模块,提供依赖
+// 3. Inject:注入标记
+// 4. Provides:提供方法
+```
+
+---
+
+## 依赖注入
+
+### 依赖注入方式
+
+```java
+// 1. 构造函数注入
+public class UserRepository {
+ private ApiService apiService;
+
+ @Inject
+ public UserRepository(ApiService apiService) {
+ this.apiService = apiService;
+ }
+}
+
+// 2. 字段注入
+public class MainActivity extends AppCompatActivity {
+ @Inject
+ UserRepository userRepository;
+}
+
+// 3. 方法注入
+@Inject
+void setUserRepository(UserRepository userRepository) {
+ this.userRepository = userRepository;
+}
+```
+
+---
+
+## 注解处理
+
+### 注解类型
+
+```java
+// @Inject:标记需要注入的依赖
+@Inject
+UserRepository userRepository;
+
+// @Module:提供依赖的模块
+@Module
+public class AppModule {
+ @Provides
+ ApiService provideApiService() {
+ return new ApiService();
+ }
+}
+
+// @Component:注入器
+@Component(modules = {AppModule.class})
+public interface AppComponent {
+ void inject(MainActivity activity);
+}
+```
+
+---
+
+## 组件与模块
+
+### Module
+
+```java
+@Module
+public class AppModule {
+ @Provides
+ @Singleton
+ ApiService provideApiService() {
+ return new ApiService();
+ }
+}
+```
+
+### Component
+
+```java
+@Component(modules = {AppModule.class})
+public interface AppComponent {
+ void inject(MainActivity activity);
+}
+
+// 使用
+AppComponent component = DaggerAppComponent.builder()
+ .appModule(new AppModule())
+ .build();
+component.inject(this);
+```
+
+---
+
+## Dagger2源码分析
+
+### 关键类
+
+```java
+// Component:组件接口
+// Module:模块类
+// Inject:注入注解
+// DaggerXXX:生成的组件实现
+```
+
+### 编译时生成
+
+```java
+// 编译时生成 DaggerAppComponent
+// 实现 AppComponent 接口
+// 提供依赖注入逻辑
+```
+
+---
+
+## Dagger2最佳实践
+
+### 1. 使用单例
+
+```java
+@Provides
+@Singleton
+ApiService provideApiService() {
+ return new ApiService();
+}
+```
+
+### 2. 模块化设计
+
+```java
+// 按功能划分模块
+@Module
+public class NetworkModule { }
+
+@Module
+public class DatabaseModule { }
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Dagger2 的原理?
+
+**答案:**
+- 编译时生成代码
+- 实现依赖注入
+- 类型安全,性能好
+
+### Q2: Dagger2 和 Hilt 的区别?
+
+**答案:**
+- **Dagger2**:基础框架,需要手动配置
+- **Hilt**:Dagger2 的封装,更易用,官方推荐
+
+### Q3: 依赖注入的优势?
+
+**答案:**
+1. 解耦:降低耦合度
+2. 测试:易于测试
+3. 复用:代码复用
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/EventBus原理.md b/docs/android面试/开源框架/EventBus原理.md
new file mode 100644
index 0000000..1ff5236
--- /dev/null
+++ b/docs/android面试/开源框架/EventBus原理.md
@@ -0,0 +1,160 @@
+# EventBus原理
+
+## 目录
+- [EventBus原理](#eventbus原理)
+- [事件总线](#事件总线)
+- [订阅机制](#订阅机制)
+- [线程模式](#线程模式)
+- [EventBus源码分析](#eventbus源码分析)
+- [EventBus最佳实践](#eventbus最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## EventBus原理
+
+### 定义
+
+```java
+// EventBus:事件总线
+// 基于观察者模式
+// 组件间解耦通信
+```
+
+### 核心概念
+
+```java
+// 1. Event:事件
+// 2. Subscriber:订阅者
+// 3. Publisher:发布者
+```
+
+---
+
+## 事件总线
+
+### 架构
+
+```java
+// EventBus 使用单例模式
+// 维护订阅者列表
+// 事件发布时,通知所有订阅者
+```
+
+---
+
+## 订阅机制
+
+### 订阅事件
+
+```java
+// 注册订阅者
+EventBus.getDefault().register(this);
+
+// 订阅方法
+@Subscribe
+public void onEvent(MessageEvent event) {
+ // 处理事件
+}
+
+// 注销订阅者
+EventBus.getDefault().unregister(this);
+```
+
+### 发布事件
+
+```java
+// 发布事件
+EventBus.getDefault().post(new MessageEvent("Hello"));
+```
+
+---
+
+## 线程模式
+
+### 线程模式类型
+
+```java
+// 1. POSTING:发布线程(默认)
+@Subscribe(threadMode = ThreadMode.POSTING)
+
+// 2. MAIN:主线程
+@Subscribe(threadMode = ThreadMode.MAIN)
+
+// 3. BACKGROUND:后台线程
+@Subscribe(threadMode = ThreadMode.BACKGROUND)
+
+// 4. ASYNC:异步线程
+@Subscribe(threadMode = ThreadMode.ASYNC)
+```
+
+---
+
+## EventBus源码分析
+
+### 关键类
+
+```java
+// EventBus:事件总线
+// SubscriberMethodFinder:订阅方法查找
+// Subscription:订阅信息
+```
+
+### 关键流程
+
+```java
+// 1. register():注册订阅者
+// 2. findSubscriberMethods():查找订阅方法
+// 3. post():发布事件
+// 4. postToSubscription():通知订阅者
+```
+
+---
+
+## EventBus最佳实践
+
+### 1. 及时注销
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ EventBus.getDefault().unregister(this);
+}
+```
+
+### 2. 使用合适的线程模式
+
+```java
+// 根据需求选择线程模式
+@Subscribe(threadMode = ThreadMode.MAIN)
+```
+
+---
+
+## 面试常见问题
+
+### Q1: EventBus 的原理?
+
+**答案:**
+- 基于观察者模式
+- 维护订阅者列表
+- 事件发布时通知所有订阅者
+
+### Q2: EventBus 的线程模式?
+
+**答案:**
+1. POSTING:发布线程
+2. MAIN:主线程
+3. BACKGROUND:后台线程
+4. ASYNC:异步线程
+
+### Q3: EventBus 的优缺点?
+
+**答案:**
+- **优点**:解耦、易用
+- **缺点**:可能内存泄漏、难以追踪
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/Glide原理.md b/docs/android面试/开源框架/Glide原理.md
new file mode 100644
index 0000000..44daeb7
--- /dev/null
+++ b/docs/android面试/开源框架/Glide原理.md
@@ -0,0 +1,173 @@
+# Glide原理
+
+## 目录
+- [Glide架构](#glide架构)
+- [图片加载流程](#图片加载流程)
+- [缓存机制](#缓存机制)
+- [内存管理](#内存管理)
+- [Glide源码分析](#glide源码分析)
+- [Glide最佳实践](#glide最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Glide架构
+
+### 架构图
+
+```
+Request → Engine → DecodeJob → DataFetcher → ModelLoader
+ ↓ ↓ ↓ ↓
+ Memory Disk Network Resource
+ Cache Cache Cache
+```
+
+### 核心组件
+
+```java
+// 1. RequestManager:请求管理
+// 2. Engine:引擎,协调加载
+// 3. DecodeJob:解码任务
+// 4. ModelLoader:模型加载器
+// 5. ResourceCache:资源缓存
+```
+
+---
+
+## 图片加载流程
+
+### 加载流程
+
+```
+1. Glide.with().load().into()
+2. RequestManager 创建 Request
+3. Engine 检查缓存
+4. 缓存未命中,创建 DecodeJob
+5. 从网络/磁盘加载
+6. 解码图片
+7. 转换和缓存
+8. 显示到 ImageView
+```
+
+### 代码示例
+
+```java
+Glide.with(context)
+ .load(url)
+ .placeholder(R.drawable.placeholder)
+ .error(R.drawable.error)
+ .override(200, 200)
+ .into(imageView);
+```
+
+---
+
+## 缓存机制
+
+### 三级缓存
+
+```java
+// 1. 活动资源缓存(Active Resources)
+// 2. 内存缓存(Memory Cache)
+// 3. 磁盘缓存(Disk Cache)
+```
+
+### 缓存策略
+
+```java
+// 默认策略:ALL
+// - 原始图片缓存到磁盘
+// - 转换后图片缓存到内存和磁盘
+
+Glide.with(context)
+ .load(url)
+ .diskCacheStrategy(DiskCacheStrategy.ALL)
+ .into(imageView);
+```
+
+---
+
+## 内存管理
+
+### 内存优化
+
+```java
+// 1. 自动管理 Bitmap 内存
+// 2. 根据 ImageView 大小加载
+// 3. 及时释放资源
+```
+
+### 内存缓存
+
+```java
+// LRU 缓存
+// 最近最少使用的图片会被回收
+```
+
+---
+
+## Glide源码分析
+
+### 关键类
+
+```java
+// Glide:入口类
+// RequestManager:请求管理
+// Engine:引擎
+// DecodeJob:解码任务
+// BitmapPool:Bitmap 对象池
+```
+
+---
+
+## Glide最佳实践
+
+### 1. 使用合适的缓存策略
+
+```java
+// 根据场景选择缓存策略
+.diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存所有
+.diskCacheStrategy(DiskCacheStrategy.NONE) // 不缓存
+```
+
+### 2. 设置图片大小
+
+```java
+// 根据 ImageView 大小加载
+.override(200, 200)
+```
+
+### 3. 处理加载失败
+
+```java
+.error(R.drawable.error)
+.fallback(R.drawable.fallback)
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Glide 的缓存机制?
+
+**答案:**
+- 三级缓存:活动资源、内存、磁盘
+- LRU 算法管理缓存
+- 自动管理内存
+
+### Q2: Glide 和 Picasso 的区别?
+
+**答案:**
+- **Glide**:功能更丰富,内存管理更好
+- **Picasso**:更轻量,API 更简单
+
+### Q3: Glide 如何避免内存泄漏?
+
+**答案:**
+- 使用生命周期感知
+- 自动取消请求
+- 及时释放资源
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/Jetpack组件.md b/docs/android面试/开源框架/Jetpack组件.md
new file mode 100644
index 0000000..86f4205
--- /dev/null
+++ b/docs/android面试/开源框架/Jetpack组件.md
@@ -0,0 +1,254 @@
+# Jetpack组件
+
+## 目录
+- [Lifecycle](#lifecycle)
+- [ViewModel](#viewmodel)
+- [LiveData](#livedata)
+- [Room](#room)
+- [Navigation](#navigation)
+- [WorkManager](#workmanager)
+- [Paging](#paging)
+- [DataBinding](#databinding)
+- [Jetpack最佳实践](#jetpack最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Lifecycle
+
+### Lifecycle 简介
+
+```java
+// Lifecycle:生命周期感知组件
+// 自动管理生命周期相关的操作
+```
+
+### 使用方式
+
+```java
+// 实现 LifecycleObserver
+public class MyObserver implements LifecycleObserver {
+ @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
+ public void onResume() {
+ // Activity onResume 时调用
+ }
+}
+
+// 注册观察者
+lifecycle.addObserver(new MyObserver());
+```
+
+---
+
+## ViewModel
+
+### ViewModel 简介
+
+```java
+// ViewModel:保存 UI 相关数据
+// 在配置变更时保持数据
+```
+
+### 使用方式
+
+```java
+public class MyViewModel extends ViewModel {
+ private MutableLiveData data = new MutableLiveData<>();
+
+ public LiveData getData() {
+ return data;
+ }
+
+ public void setData(String value) {
+ data.setValue(value);
+ }
+}
+
+// Activity 中使用
+MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
+viewModel.getData().observe(this, data -> {
+ // 更新 UI
+});
+```
+
+---
+
+## LiveData
+
+### LiveData 简介
+
+```java
+// LiveData:可观察的数据持有者
+// 自动更新 UI
+// 生命周期感知
+```
+
+### 使用方式
+
+```java
+MutableLiveData liveData = new MutableLiveData<>();
+liveData.observe(this, new Observer() {
+ @Override
+ public void onChanged(String s) {
+ // 数据变化时自动更新
+ }
+});
+
+liveData.setValue("New Value");
+```
+
+---
+
+## Room
+
+### Room 简介
+
+```java
+// Room:SQLite 数据库抽象层
+// 编译时检查
+// 支持 LiveData、RxJava
+```
+
+### 使用方式
+
+```java
+@Database(entities = {User.class}, version = 1)
+public abstract class AppDatabase extends RoomDatabase {
+ public abstract UserDao userDao();
+}
+
+@Dao
+public interface UserDao {
+ @Query("SELECT * FROM user")
+ LiveData> getAllUsers();
+}
+```
+
+---
+
+## Navigation
+
+### Navigation 简介
+
+```java
+// Navigation:导航组件
+// 简化 Fragment 导航
+```
+
+### 使用方式
+
+```java
+// 导航到目标
+Navigation.findNavController(view)
+ .navigate(R.id.action_fragmentA_to_fragmentB);
+```
+
+---
+
+## WorkManager
+
+### WorkManager 简介
+
+```java
+// WorkManager:后台任务管理
+// 保证任务执行
+// 支持约束条件
+```
+
+### 使用方式
+
+```java
+WorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
+ .setConstraints(new Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .build())
+ .build();
+
+WorkManager.getInstance(context).enqueue(workRequest);
+```
+
+---
+
+## Paging
+
+### Paging 简介
+
+```java
+// Paging:分页加载数据
+// 自动处理分页逻辑
+```
+
+---
+
+## DataBinding
+
+### DataBinding 简介
+
+```java
+// DataBinding:数据绑定
+// 减少 findViewById
+// 自动更新 UI
+```
+
+### 使用方式
+
+```xml
+
+
+
+
+
+
+```
+
+---
+
+## Jetpack最佳实践
+
+### 1. 使用 ViewModel 保存数据
+
+```java
+// 配置变更时保持数据
+```
+
+### 2. 使用 LiveData 更新 UI
+
+```java
+// 自动更新,生命周期感知
+```
+
+### 3. 使用 Room 管理数据
+
+```java
+// 类型安全,编译时检查
+```
+
+---
+
+## 面试常见问题
+
+### Q1: ViewModel 的作用?
+
+**答案:**
+- 保存 UI 相关数据
+- 在配置变更时保持数据
+- 与 Activity/Fragment 生命周期分离
+
+### Q2: LiveData 的特点?
+
+**答案:**
+- 可观察
+- 生命周期感知
+- 自动更新 UI
+
+### Q3: Room 的优势?
+
+**答案:**
+- 编译时检查
+- 类型安全
+- 支持 LiveData、RxJava
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/Picasso原理.md b/docs/android面试/开源框架/Picasso原理.md
new file mode 100644
index 0000000..ab148e0
--- /dev/null
+++ b/docs/android面试/开源框架/Picasso原理.md
@@ -0,0 +1,128 @@
+# Picasso原理
+
+## 目录
+- [Picasso架构](#picasso架构)
+- [图片加载流程](#图片加载流程)
+- [缓存机制](#缓存机制)
+- [Picasso源码分析](#picasso源码分析)
+- [Picasso最佳实践](#picasso最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Picasso架构
+
+### 架构图
+
+```
+Request → Dispatcher → BitmapHunter → NetworkRequest
+ ↓ ↓ ↓
+ Memory Disk Bitmap
+ Cache Cache Decode
+```
+
+### 核心组件
+
+```java
+// 1. Picasso:入口类
+// 2. RequestCreator:请求创建器
+// 3. Dispatcher:调度器
+// 4. BitmapHunter:图片加载器
+// 5. Cache:缓存
+```
+
+---
+
+## 图片加载流程
+
+### 加载流程
+
+```
+1. Picasso.with().load().into()
+2. 检查内存缓存
+3. 检查磁盘缓存
+4. 从网络加载
+5. 解码图片
+6. 缓存图片
+7. 显示到 ImageView
+```
+
+### 代码示例
+
+```java
+Picasso.get()
+ .load(url)
+ .placeholder(R.drawable.placeholder)
+ .error(R.drawable.error)
+ .resize(200, 200)
+ .into(imageView);
+```
+
+---
+
+## 缓存机制
+
+### 二级缓存
+
+```java
+// 1. 内存缓存:LruCache
+// 2. 磁盘缓存:OkHttp 缓存
+```
+
+### 缓存策略
+
+```java
+// 默认缓存策略
+// - 内存缓存:自动管理
+// - 磁盘缓存:使用 OkHttp 缓存
+```
+
+---
+
+## Picasso源码分析
+
+### 关键类
+
+```java
+// Picasso:入口类
+// RequestCreator:请求创建
+// Dispatcher:任务调度
+// BitmapHunter:图片加载
+```
+
+---
+
+## Picasso最佳实践
+
+### 1. 设置图片大小
+
+```java
+// 根据 ImageView 大小加载
+.resize(200, 200)
+```
+
+### 2. 处理加载失败
+
+```java
+.error(R.drawable.error)
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Picasso 和 Glide 的区别?
+
+**答案:**
+- **Picasso**:更轻量,API 简单,功能基础
+- **Glide**:功能丰富,内存管理更好,支持 GIF
+
+### Q2: Picasso 的缓存机制?
+
+**答案:**
+- 二级缓存:内存缓存、磁盘缓存
+- 使用 LruCache 管理内存缓存
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/开源框架/RxJava原理.md b/docs/android面试/开源框架/RxJava原理.md
new file mode 100644
index 0000000..8e6c404
--- /dev/null
+++ b/docs/android面试/开源框架/RxJava原理.md
@@ -0,0 +1,185 @@
+# RxJava原理
+
+## 目录
+- [RxJava概念](#rxjava概念)
+- [观察者模式](#观察者模式)
+- [操作符](#操作符)
+- [线程调度](#线程调度)
+- [背压](#背压)
+- [RxJava源码分析](#rxjava源码分析)
+- [RxJava最佳实践](#rxjava最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## RxJava概念
+
+### 定义
+
+```java
+// RxJava:响应式编程库
+// - 基于观察者模式
+// - 支持异步操作
+// - 链式调用
+```
+
+### 核心类
+
+```java
+// Observable:被观察者
+// Observer:观察者
+// Subscriber:订阅者
+// Scheduler:调度器
+```
+
+---
+
+## 观察者模式
+
+### 基本使用
+
+```java
+Observable.create(new ObservableOnSubscribe() {
+ @Override
+ public void subscribe(ObservableEmitter emitter) {
+ emitter.onNext("Hello");
+ emitter.onNext("World");
+ emitter.onComplete();
+ }
+})
+.subscribe(new Observer() {
+ @Override
+ public void onSubscribe(Disposable d) {
+ }
+
+ @Override
+ public void onNext(String s) {
+ System.out.println(s);
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ }
+
+ @Override
+ public void onComplete() {
+ }
+});
+```
+
+---
+
+## 操作符
+
+### 常用操作符
+
+```java
+// map:转换
+Observable.just(1, 2, 3)
+ .map(i -> i * 2)
+ .subscribe(System.out::println);
+
+// filter:过滤
+Observable.just(1, 2, 3, 4, 5)
+ .filter(i -> i % 2 == 0)
+ .subscribe(System.out::println);
+
+// flatMap:扁平化
+Observable.just(1, 2, 3)
+ .flatMap(i -> Observable.just(i * 2))
+ .subscribe(System.out::println);
+```
+
+---
+
+## 线程调度
+
+### Scheduler
+
+```java
+// subscribeOn:指定上游线程
+// observeOn:指定下游线程
+
+Observable.create(...)
+ .subscribeOn(Schedulers.io()) // 在 IO 线程执行
+ .observeOn(AndroidSchedulers.mainThread()) // 在主线程观察
+ .subscribe(...);
+```
+
+---
+
+## 背压
+
+### 背压问题
+
+```java
+// 当生产速度 > 消费速度时,产生背压
+// 可能导致内存溢出
+```
+
+### 解决方案
+
+```java
+// 使用 Flowable
+Flowable.create(...)
+ .onBackpressureBuffer() // 缓冲
+ .subscribe(...);
+```
+
+---
+
+## RxJava源码分析
+
+### 关键类
+
+```java
+// Observable:被观察者
+// Observer:观察者
+// Scheduler:调度器
+// Operator:操作符
+```
+
+---
+
+## RxJava最佳实践
+
+### 1. 及时取消订阅
+
+```java
+Disposable disposable = observable.subscribe(...);
+disposable.dispose(); // 取消订阅
+```
+
+### 2. 使用合适的操作符
+
+```java
+// 根据需求选择操作符
+// map、filter、flatMap 等
+```
+
+---
+
+## 面试常见问题
+
+### Q1: RxJava 的原理?
+
+**答案:**
+- 基于观察者模式
+- 支持链式调用
+- 支持线程调度
+
+### Q2: subscribeOn 和 observeOn 的区别?
+
+**答案:**
+- **subscribeOn**:指定上游线程
+- **observeOn**:指定下游线程
+
+### Q3: RxJava 的背压?
+
+**答案:**
+- 生产速度 > 消费速度时产生
+- 使用 Flowable 处理
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/性能优化/内存优化.md b/docs/android面试/性能优化/内存优化.md
new file mode 100644
index 0000000..d4d0d06
--- /dev/null
+++ b/docs/android面试/性能优化/内存优化.md
@@ -0,0 +1,734 @@
+# 内存优化
+
+## 目录
+- [内存泄漏](#内存泄漏)
+- [内存抖动](#内存抖动)
+- [内存分析工具](#内存分析工具)
+- [内存优化方案](#内存优化方案)
+- [图片内存优化](#图片内存优化)
+- [对象池](#对象池)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 内存泄漏
+
+### 什么是内存泄漏?
+
+内存泄漏是指程序在运行过程中,由于某些原因导致无法释放已经不再使用的内存,造成内存浪费,最终可能导致 OOM(OutOfMemoryError)。
+
+### 常见内存泄漏场景
+
+#### 1. 静态变量持有 Context
+
+```java
+// ❌ 错误示例
+public class MyActivity extends AppCompatActivity {
+ private static Context sContext;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ sContext = this; // 静态变量持有 Activity,导致泄漏
+ }
+}
+
+// ✅ 正确做法
+public class MyActivity extends AppCompatActivity {
+ private static Context sContext;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ sContext = getApplicationContext(); // 使用 Application Context
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ sContext = null; // 及时释放
+ }
+}
+```
+
+#### 2. Handler 内存泄漏
+
+```java
+// ❌ 错误示例
+public class MyActivity extends AppCompatActivity {
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Handler 持有 Activity 的隐式引用
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // 如果 Activity 已销毁,但 Handler 还在处理消息,导致泄漏
+ }
+ }, 10000);
+ }
+}
+
+// ✅ 正确做法
+public class MyActivity extends AppCompatActivity {
+ private Handler mHandler;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (MyActivity.this.isFinishing()) {
+ return; // Activity 已销毁,不处理消息
+ }
+ // 处理消息
+ }
+ };
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mHandler.removeCallbacksAndMessages(null); // 移除所有消息
+ }
+}
+
+// ✅ 使用静态内部类 + WeakReference
+public class MyActivity extends AppCompatActivity {
+ private static class MyHandler extends Handler {
+ private WeakReference mActivity;
+
+ MyHandler(MyActivity activity) {
+ mActivity = new WeakReference<>(activity);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ MyActivity activity = mActivity.get();
+ if (activity == null || activity.isFinishing()) {
+ return;
+ }
+ // 处理消息
+ }
+ }
+}
+```
+
+#### 3. 单例模式持有 Context
+
+```java
+// ❌ 错误示例
+public class Singleton {
+ private static Singleton instance;
+ private Context mContext;
+
+ private Singleton(Context context) {
+ this.mContext = context; // 持有 Activity Context
+ }
+
+ public static Singleton getInstance(Context context) {
+ if (instance == null) {
+ instance = new Singleton(context);
+ }
+ return instance;
+ }
+}
+
+// ✅ 正确做法
+public class Singleton {
+ private static Singleton instance;
+ private Context mContext;
+
+ private Singleton(Context context) {
+ this.mContext = context.getApplicationContext(); // 使用 Application Context
+ }
+
+ public static Singleton getInstance(Context context) {
+ if (instance == null) {
+ synchronized (Singleton.class) {
+ if (instance == null) {
+ instance = new Singleton(context);
+ }
+ }
+ }
+ return instance;
+ }
+}
+```
+
+#### 4. 内部类持有外部类引用
+
+```java
+// ❌ 错误示例
+public class MyActivity extends AppCompatActivity {
+ private MyAsyncTask mTask;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mTask = new MyAsyncTask(); // 内部类持有 Activity 引用
+ mTask.execute();
+ }
+
+ private class MyAsyncTask extends AsyncTask {
+ @Override
+ protected Void doInBackground(Void... voids) {
+ // 耗时操作
+ return null;
+ }
+ }
+}
+
+// ✅ 正确做法:使用静态内部类
+public class MyActivity extends AppCompatActivity {
+ private MyAsyncTask mTask;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mTask = new MyAsyncTask(this);
+ mTask.execute();
+ }
+
+ private static class MyAsyncTask extends AsyncTask {
+ private WeakReference mActivity;
+
+ MyAsyncTask(MyActivity activity) {
+ mActivity = new WeakReference<>(activity);
+ }
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+ // 耗时操作
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void aVoid) {
+ MyActivity activity = mActivity.get();
+ if (activity == null || activity.isFinishing()) {
+ return;
+ }
+ // 更新 UI
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mTask != null) {
+ mTask.cancel(true);
+ }
+ }
+}
+```
+
+#### 5. 监听器未注销
+
+```java
+// ❌ 错误示例
+public class MyActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
+ Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
+ // 忘记注销监听器
+ }
+}
+
+// ✅ 正确做法
+public class MyActivity extends AppCompatActivity {
+ private SensorManager mSensorManager;
+ private Sensor mSensor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
+ mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mSensorManager != null) {
+ mSensorManager.unregisterListener(this); // 注销监听器
+ }
+ }
+}
+```
+
+#### 6. 集合类持有对象引用
+
+```java
+// ❌ 错误示例
+public class MyActivity extends AppCompatActivity {
+ private static List sViews = new ArrayList<>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ View view = findViewById(R.id.view);
+ sViews.add(view); // 静态集合持有 View,View 持有 Activity,导致泄漏
+ }
+}
+
+// ✅ 正确做法
+public class MyActivity extends AppCompatActivity {
+ private static List> sViews = new ArrayList<>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ View view = findViewById(R.id.view);
+ sViews.add(new WeakReference<>(view));
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ // 清理集合
+ sViews.clear();
+ }
+}
+```
+
+---
+
+## 内存抖动
+
+### 什么是内存抖动?
+
+内存抖动是指短时间内频繁分配和回收内存,导致 GC 频繁执行,影响应用性能。
+
+### 内存抖动的原因
+
+1. **频繁创建对象**:在循环中创建大量临时对象
+2. **字符串拼接**:使用 `+` 拼接字符串
+3. **集合扩容**:集合频繁扩容导致内存分配
+
+### 内存抖动示例
+
+```java
+// ❌ 错误示例:频繁创建对象
+for (int i = 0; i < 10000; i++) {
+ String str = new String("Hello" + i); // 每次循环都创建新对象
+ list.add(str);
+}
+
+// ✅ 正确做法:使用 StringBuilder
+StringBuilder sb = new StringBuilder();
+for (int i = 0; i < 10000; i++) {
+ sb.append("Hello").append(i);
+ list.add(sb.toString());
+ sb.setLength(0); // 清空 StringBuilder
+}
+
+// ❌ 错误示例:字符串拼接
+String result = "";
+for (int i = 0; i < 1000; i++) {
+ result += "item" + i; // 每次拼接都创建新对象
+}
+
+// ✅ 正确做法:使用 StringBuilder
+StringBuilder sb = new StringBuilder();
+for (int i = 0; i < 1000; i++) {
+ sb.append("item").append(i);
+}
+String result = sb.toString();
+```
+
+---
+
+## 内存分析工具
+
+### 1. LeakCanary
+
+#### 集成 LeakCanary
+```gradle
+dependencies {
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
+}
+```
+
+#### 使用
+```java
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (LeakCanary.isInAnalyzerProcess(this)) {
+ return;
+ }
+ LeakCanary.install(this);
+ }
+}
+```
+
+### 2. Android Studio Memory Profiler
+
+- 实时查看内存使用
+- 查看内存分配
+- 查看内存泄漏
+- 生成 Heap Dump
+
+### 3. MAT (Memory Analyzer Tool)
+
+- 分析 Heap Dump
+- 查找内存泄漏
+- 查看对象引用关系
+
+### 4. adb 命令
+
+```bash
+# 查看内存信息
+adb shell dumpsys meminfo
+
+# 查看进程内存
+adb shell dumpsys meminfo
+
+# 强制 GC
+adb shell am force-stop
+```
+
+---
+
+## 内存优化方案
+
+### 1. 使用对象池
+
+```java
+public class ObjectPool {
+ private Queue pool = new LinkedList<>();
+ private Supplier factory;
+ private int maxSize;
+
+ public ObjectPool(Supplier factory, int maxSize) {
+ this.factory = factory;
+ this.maxSize = maxSize;
+ }
+
+ public T acquire() {
+ T obj = pool.poll();
+ if (obj == null) {
+ obj = factory.get();
+ }
+ return obj;
+ }
+
+ public void release(T obj) {
+ if (pool.size() < maxSize) {
+ pool.offer(obj);
+ }
+ }
+}
+
+// 使用
+ObjectPool pool = new ObjectPool<>(
+ StringBuilder::new, 10
+);
+StringBuilder sb = pool.acquire();
+// 使用 sb
+pool.release(sb);
+```
+
+### 2. 使用弱引用
+
+```java
+// WeakReference:GC 时会被回收
+WeakReference weakRef = new WeakReference<>(activity);
+Activity activity = weakRef.get();
+if (activity == null) {
+ // 已被回收
+}
+
+// SoftReference:内存不足时会被回收
+SoftReference softRef = new SoftReference<>(bitmap);
+Bitmap bitmap = softRef.get();
+if (bitmap == null) {
+ // 已被回收
+}
+```
+
+### 3. 及时释放资源
+
+```java
+public class MyActivity extends AppCompatActivity {
+ private Bitmap mBitmap;
+ private FileInputStream mInputStream;
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+
+ // 释放 Bitmap
+ if (mBitmap != null && !mBitmap.isRecycled()) {
+ mBitmap.recycle();
+ mBitmap = null;
+ }
+
+ // 关闭流
+ if (mInputStream != null) {
+ try {
+ mInputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ mInputStream = null;
+ }
+ }
+}
+```
+
+### 4. 使用 SparseArray 替代 HashMap
+
+```java
+// HashMap 会创建 Integer 对象
+HashMap map = new HashMap<>();
+
+// SparseArray 避免自动装箱
+SparseArray sparseArray = new SparseArray<>();
+sparseArray.put(1, "value");
+```
+
+### 5. 避免在 onDraw 中创建对象
+
+```java
+// ❌ 错误示例
+@Override
+protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ Paint paint = new Paint(); // 每次绘制都创建新对象
+ canvas.drawText("Hello", 0, 0, paint);
+}
+
+// ✅ 正确做法
+public class MyView extends View {
+ private Paint mPaint; // 复用 Paint 对象
+
+ public MyView(Context context) {
+ super(context);
+ mPaint = new Paint();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.drawText("Hello", 0, 0, mPaint);
+ }
+}
+```
+
+---
+
+## 图片内存优化
+
+### 1. 图片压缩
+
+```java
+public Bitmap compressBitmap(Bitmap bitmap, int maxWidth, int maxHeight) {
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+
+ float scale = Math.min((float) maxWidth / width, (float) maxHeight / height);
+ if (scale < 1.0f) {
+ int newWidth = Math.round(width * scale);
+ int newHeight = Math.round(height * scale);
+ return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
+ }
+ return bitmap;
+}
+```
+
+### 2. 使用合适的图片格式
+
+- **WebP**:压缩率高,支持透明
+- **PNG**:无损压缩,适合图标
+- **JPEG**:有损压缩,适合照片
+
+### 3. 使用 inSampleSize
+
+```java
+public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeResource(res, resId, options);
+
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeResource(res, resId, options);
+}
+
+private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
+ int height = options.outHeight;
+ int width = options.outWidth;
+ int inSampleSize = 1;
+
+ if (height > reqHeight || width > reqWidth) {
+ int halfHeight = height / 2;
+ int halfWidth = width / 2;
+ while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
+ inSampleSize *= 2;
+ }
+ }
+ return inSampleSize;
+}
+```
+
+### 4. 使用 RGB_565
+
+```java
+BitmapFactory.Options options = new BitmapFactory.Options();
+options.inPreferredConfig = Bitmap.Config.RGB_565; // 减少内存占用
+Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image, options);
+```
+
+### 5. 及时回收 Bitmap
+
+```java
+if (bitmap != null && !bitmap.isRecycled()) {
+ bitmap.recycle();
+ bitmap = null;
+}
+```
+
+---
+
+## 对象池
+
+### 实现对象池
+
+```java
+public class RecyclerPool {
+ private final Queue pool = new LinkedList<>();
+ private final Supplier factory;
+ private final Consumer reset;
+ private final int maxSize;
+
+ public RecyclerPool(Supplier factory, Consumer reset, int maxSize) {
+ this.factory = factory;
+ this.reset = reset;
+ this.maxSize = maxSize;
+ }
+
+ public T acquire() {
+ T obj = pool.poll();
+ if (obj == null) {
+ obj = factory.get();
+ }
+ return obj;
+ }
+
+ public void release(T obj) {
+ if (obj == null) {
+ return;
+ }
+ reset.accept(obj);
+ if (pool.size() < maxSize) {
+ pool.offer(obj);
+ }
+ }
+
+ public void clear() {
+ pool.clear();
+ }
+}
+
+// 使用示例
+RecyclerPool pool = new RecyclerPool<>(
+ StringBuilder::new,
+ sb -> sb.setLength(0),
+ 10
+);
+
+StringBuilder sb = pool.acquire();
+sb.append("Hello");
+// 使用完毕
+pool.release(sb);
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是内存泄漏?如何避免?
+
+**答案:**
+- 内存泄漏是指程序无法释放不再使用的内存
+- 常见原因:静态变量持有 Context、Handler 未移除消息、监听器未注销等
+- 避免方法:使用 Application Context、使用 WeakReference、及时注销监听器等
+
+### Q2: Handler 为什么会导致内存泄漏?
+
+**答案:**
+- Handler 持有 Activity 的隐式引用
+- Message 持有 Handler 的引用
+- MessageQueue 持有 Message 的引用
+- 如果 Handler 还有未处理的消息,Activity 就无法被回收
+
+### Q3: 如何检测内存泄漏?
+
+**答案:**
+1. 使用 LeakCanary 自动检测
+2. 使用 Android Studio Memory Profiler
+3. 使用 MAT 分析 Heap Dump
+4. 使用 adb dumpsys meminfo 命令
+
+### Q4: 什么是内存抖动?如何避免?
+
+**答案:**
+- 内存抖动是短时间内频繁分配和回收内存
+- 避免方法:使用对象池、使用 StringBuilder、避免在循环中创建对象
+
+### Q5: 如何优化图片内存?
+
+**答案:**
+1. 使用合适的图片格式(WebP、PNG、JPEG)
+2. 使用 inSampleSize 压缩
+3. 使用 RGB_565 减少内存
+4. 及时回收 Bitmap
+5. 使用图片加载库(Glide、Picasso)
+
+### Q6: Context 的使用注意事项?
+
+**答案:**
+- Activity Context:生命周期短,不能长期持有
+- Application Context:生命周期长,可以长期持有
+- 静态变量、单例等应使用 Application Context
+
+### Q7: 如何优化内存使用?
+
+**答案:**
+1. 避免内存泄漏
+2. 使用对象池复用对象
+3. 使用弱引用
+4. 及时释放资源
+5. 优化图片内存
+6. 使用 SparseArray 替代 HashMap
+
+---
+
+## 总结
+
+内存优化是 Android 性能优化的重要部分,主要从以下几个方面入手:
+
+1. **避免内存泄漏**:注意 Context、Handler、监听器的使用
+2. **避免内存抖动**:减少对象创建,使用对象池
+3. **优化图片内存**:压缩、使用合适格式、及时回收
+4. **使用工具检测**:LeakCanary、Memory Profiler、MAT
+
+通过合理的内存优化,可以避免 OOM,提升应用性能。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/性能优化/启动优化.md b/docs/android面试/性能优化/启动优化.md
new file mode 100644
index 0000000..45f8153
--- /dev/null
+++ b/docs/android面试/性能优化/启动优化.md
@@ -0,0 +1,557 @@
+# 启动优化
+
+## 目录
+- [启动流程分析](#启动流程分析)
+- [启动时间测量](#启动时间测量)
+- [冷启动优化](#冷启动优化)
+- [热启动优化](#热启动优化)
+- [启动优化方案](#启动优化方案)
+- [启动优化工具](#启动优化工具)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 启动流程分析
+
+### 应用启动类型
+
+#### 1. 冷启动(Cold Start)
+- **定义**:系统进程中没有该应用的任何进程信息,需要创建新进程
+- **特点**:启动时间最长,需要加载所有资源
+- **流程**:
+ 1. 启动进程
+ 2. 创建Application对象
+ 3. 启动主线程
+ 4. 创建主Activity
+ 5. 加载布局
+ 6. 执行onCreate
+ 7. 测量、布局、绘制
+ 8. 显示到屏幕
+
+#### 2. 热启动(Hot Start)
+- **定义**:应用进程还在,只是Activity被销毁
+- **特点**:启动时间短,只需恢复Activity
+- **流程**:
+ 1. 恢复Activity
+ 2. 调用onCreate、onStart、onResume
+ 3. 显示到屏幕
+
+#### 3. 温启动(Warm Start)
+- **定义**:应用进程存在,但Activity需要重建
+- **特点**:介于冷启动和热启动之间
+
+### 启动时间线
+
+```
+进程创建 → Application创建 → Activity创建 → 布局加载 → 首帧绘制
+```
+
+---
+
+## 启动时间测量
+
+### 1. 使用 adb 命令测量
+
+```bash
+# 测量冷启动时间
+adb shell am start -W -n com.example.app/.MainActivity
+
+# 输出示例:
+# ThisTime: 500ms # 最后一个Activity启动耗时
+# TotalTime: 800ms # 所有Activity启动耗时
+# WaitTime: 1000ms # 系统启动应用耗时
+```
+
+### 2. 代码中测量
+
+```java
+// Application onCreate
+@Override
+public void onCreate() {
+ super.onCreate();
+ long startTime = System.currentTimeMillis();
+
+ // 初始化代码
+
+ long endTime = System.currentTimeMillis();
+ Log.d("Startup", "Application onCreate: " + (endTime - startTime) + "ms");
+}
+
+// Activity onCreate
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ long startTime = System.currentTimeMillis();
+ super.onCreate(savedInstanceState);
+
+ // 初始化代码
+
+ long endTime = System.currentTimeMillis();
+ Log.d("Startup", "Activity onCreate: " + (endTime - startTime) + "ms");
+}
+```
+
+### 3. 使用 TraceView
+
+```java
+// 开始追踪
+Debug.startMethodTracing("startup");
+
+// 结束追踪
+Debug.stopMethodTracing();
+```
+
+### 4. 使用 Systrace/Perfetto
+
+```bash
+# 使用 Systrace
+python systrace.py -t 10 -o trace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res
+
+# 使用 Perfetto
+# 在开发者选项中启用系统追踪
+```
+
+---
+
+## 冷启动优化
+
+### 1. Application 优化
+
+#### 延迟初始化
+```java
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ // 必要初始化(立即执行)
+ initCrashHandler();
+
+ // 非必要初始化(延迟执行)
+ new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ initThirdPartySDK();
+ }, 100);
+ }
+}
+```
+
+#### 异步初始化
+```java
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ // 使用线程池异步初始化
+ ExecutorService executor = Executors.newCachedThreadPool();
+ executor.execute(() -> {
+ initHeavySDK();
+ });
+ }
+}
+```
+
+#### 使用 ContentProvider 初始化(不推荐)
+```java
+// 不推荐:ContentProvider 的 onCreate 在 Application onCreate 之前执行
+// 会阻塞主线程
+public class InitProvider extends ContentProvider {
+ @Override
+ public boolean onCreate() {
+ // 初始化代码
+ return true;
+ }
+}
+```
+
+### 2. Activity 优化
+
+#### 减少 onCreate 耗时
+```java
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // 1. 延迟非关键初始化
+ new Handler().post(() -> {
+ initNonCriticalComponents();
+ });
+
+ // 2. 使用 ViewStub 延迟加载
+ ViewStub viewStub = findViewById(R.id.view_stub);
+ viewStub.inflate(); // 需要时才加载
+
+ // 3. 异步加载数据
+ loadDataAsync();
+}
+```
+
+#### 使用启动窗口
+```xml
+
+
+```
+
+```xml
+
+
+
+
+
+
+
+```
+
+```java
+// MainActivity.java
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ setTheme(R.style.AppTheme); // 恢复正常主题
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+}
+```
+
+### 3. 布局优化
+
+#### 减少布局层级
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+#### 使用 ViewStub
+```xml
+
+```
+
+```java
+// 需要时才加载
+ViewStub viewStub = findViewById(R.id.view_stub);
+viewStub.inflate();
+```
+
+#### 使用 Merge 标签
+```xml
+
+
+
+
+
+```
+
+### 4. 资源优化
+
+#### 减少资源大小
+- 使用 WebP 格式图片
+- 压缩图片资源
+- 移除未使用的资源
+- 使用矢量图(SVG)
+
+#### 延迟加载资源
+```java
+// 使用 Glide 等图片加载库延迟加载
+Glide.with(this)
+ .load(url)
+ .into(imageView);
+```
+
+### 5. 多进程优化
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+---
+
+## 热启动优化
+
+### 1. 避免重建 Activity
+
+```java
+// 在 onSaveInstanceState 中保存状态
+@Override
+protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString("key", value);
+}
+
+// 在 onCreate 中恢复状态
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState != null) {
+ String value = savedInstanceState.getString("key");
+ }
+}
+```
+
+### 2. 使用 ViewModel
+
+```java
+public class MainViewModel extends ViewModel {
+ private MutableLiveData data = new MutableLiveData<>();
+
+ public LiveData getData() {
+ return data;
+ }
+}
+
+// Activity 中使用
+public class MainActivity extends AppCompatActivity {
+ private MainViewModel viewModel;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
+ // ViewModel 在配置变更时不会重建
+ }
+}
+```
+
+### 3. 配置变更处理
+
+```xml
+
+
+```
+
+```java
+@Override
+public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // 手动处理配置变更,避免重建 Activity
+}
+```
+
+---
+
+## 启动优化方案
+
+### 1. 启动任务管理
+
+```java
+public class StartupTaskManager {
+ private static final List tasks = new ArrayList<>();
+
+ public static void addTask(StartupTask task) {
+ tasks.add(task);
+ }
+
+ public static void executeTasks() {
+ ExecutorService executor = Executors.newCachedThreadPool();
+ for (StartupTask task : tasks) {
+ if (task.runOnMainThread()) {
+ task.run();
+ } else {
+ executor.execute(task::run);
+ }
+ }
+ }
+}
+
+interface StartupTask {
+ void run();
+ boolean runOnMainThread();
+ int priority(); // 优先级
+}
+```
+
+### 2. 启动白屏优化
+
+```java
+// 使用启动窗口主题
+
+```
+
+### 3. 预加载优化
+
+```java
+// 在 Application 中预加载
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ // 预加载常用数据
+ preloadData();
+
+ // 预初始化 View
+ preloadViews();
+ }
+
+ private void preloadData() {
+ // 预加载数据到内存
+ }
+
+ private void preloadViews() {
+ // 预创建 View 对象
+ }
+}
+```
+
+---
+
+## 启动优化工具
+
+### 1. Android Studio Profiler
+- CPU Profiler:分析启动时的 CPU 使用
+- Memory Profiler:分析内存分配
+- Network Profiler:分析网络请求
+
+### 2. Systrace/Perfetto
+- 系统级性能分析
+- 查看启动时间线
+- 分析各组件耗时
+
+### 3. TraceView
+- 方法级性能分析
+- 查看方法调用栈
+- 分析耗时方法
+
+### 4. 自定义工具
+```java
+public class StartupTracker {
+ private static final Map timings = new HashMap<>();
+
+ public static void start(String tag) {
+ timings.put(tag, System.currentTimeMillis());
+ }
+
+ public static void end(String tag) {
+ Long startTime = timings.get(tag);
+ if (startTime != null) {
+ long duration = System.currentTimeMillis() - startTime;
+ Log.d("Startup", tag + ": " + duration + "ms");
+ }
+ }
+}
+
+// 使用
+StartupTracker.start("Application.onCreate");
+// ... 代码 ...
+StartupTracker.end("Application.onCreate");
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 如何测量应用的启动时间?
+
+**答案:**
+1. 使用 `adb shell am start -W` 命令
+2. 在代码中使用 `System.currentTimeMillis()` 记录时间点
+3. 使用 TraceView 或 Systrace 工具
+4. 使用 Android Studio Profiler
+
+### Q2: 冷启动和热启动的区别?
+
+**答案:**
+- **冷启动**:系统进程中没有应用进程,需要创建新进程,耗时最长
+- **热启动**:应用进程还在,只需恢复 Activity,耗时最短
+- **温启动**:应用进程存在,但 Activity 需要重建,耗时介于两者之间
+
+### Q3: Application onCreate 中应该做什么?
+
+**答案:**
+- 只做必要的初始化
+- 非必要的初始化应该延迟或异步执行
+- 避免在主线程执行耗时操作
+- 避免初始化过多第三方 SDK
+
+### Q4: 如何优化启动速度?
+
+**答案:**
+1. **Application 优化**:延迟初始化、异步初始化
+2. **Activity 优化**:减少 onCreate 耗时、使用启动窗口
+3. **布局优化**:减少层级、使用 ViewStub、Merge 标签
+4. **资源优化**:压缩资源、使用 WebP、移除未使用资源
+5. **多进程优化**:将耗时操作放到后台进程
+
+### Q5: 启动白屏问题如何解决?
+
+**答案:**
+1. 使用启动窗口主题(Splash Theme)
+2. 设置合适的 windowBackground
+3. 使用启动画面(Splash Screen)
+4. 尽快显示首帧内容
+
+### Q6: ViewStub 的作用是什么?
+
+**答案:**
+- ViewStub 是一个轻量级的 View,用于延迟加载布局
+- 只有在调用 `inflate()` 时才会加载实际布局
+- 可以减少初始布局的复杂度,提升启动速度
+
+### Q7: 如何避免 Activity 重建?
+
+**答案:**
+1. 使用 ViewModel 保存数据
+2. 在 onSaveInstanceState 中保存状态
+3. 处理配置变更(configChanges)
+4. 使用 Fragment 保存状态
+
+### Q8: 启动优化的最佳实践?
+
+**答案:**
+1. 测量启动时间,找出瓶颈
+2. 延迟非关键初始化
+3. 异步执行耗时操作
+4. 优化布局层级
+5. 使用启动窗口
+6. 减少资源大小
+7. 使用多进程分离耗时操作
+
+---
+
+## 总结
+
+启动优化是 Android 性能优化的重要部分,主要从以下几个方面入手:
+
+1. **Application 优化**:延迟初始化、异步初始化
+2. **Activity 优化**:减少 onCreate 耗时、使用启动窗口
+3. **布局优化**:减少层级、使用 ViewStub
+4. **资源优化**:压缩资源、延迟加载
+5. **架构优化**:使用多进程、任务管理
+
+通过合理的优化,可以将冷启动时间从 2-3 秒降低到 1 秒以内。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/性能优化/布局优化.md b/docs/android面试/性能优化/布局优化.md
new file mode 100644
index 0000000..8aac63d
--- /dev/null
+++ b/docs/android面试/性能优化/布局优化.md
@@ -0,0 +1,566 @@
+# 布局优化
+
+## 目录
+- [布局层级优化](#布局层级优化)
+- [布局性能分析](#布局性能分析)
+- [ViewStub使用](#viewstub使用)
+- [Merge标签](#merge标签)
+- [Include标签](#include标签)
+- [ConstraintLayout](#constraintlayout)
+- [布局优化工具](#布局优化工具)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 布局层级优化
+
+### 减少布局层级
+
+#### 问题:嵌套过深
+```xml
+
+
+
+
+
+
+
+
+```
+
+#### 解决方案:使用 ConstraintLayout
+```xml
+
+
+
+
+
+
+```
+
+### 避免不必要的 ViewGroup
+
+```xml
+
+
+
+
+
+
+
+```
+
+### 使用 RelativeLayout 替代嵌套 LinearLayout
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+## 布局性能分析
+
+### 1. 使用 Hierarchy Viewer
+
+```bash
+# 在设备上启用 View Server
+adb shell service call window 3 i32 4939
+
+# 打开 Hierarchy Viewer
+# Tools -> Android -> Android Device Monitor -> Hierarchy Viewer
+```
+
+### 2. 使用 Layout Inspector
+
+- Android Studio -> Tools -> Layout Inspector
+- 实时查看布局层级
+- 查看 View 属性
+- 分析布局性能
+
+### 3. 使用 Systrace
+
+```bash
+# 分析布局性能
+python systrace.py -t 10 -o trace.html gfx view
+```
+
+### 4. 代码中测量
+
+```java
+public class MyActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ long startTime = System.currentTimeMillis();
+ setContentView(R.layout.activity_main);
+ long endTime = System.currentTimeMillis();
+
+ Log.d("Layout", "Layout inflation time: " + (endTime - startTime) + "ms");
+ }
+}
+```
+
+---
+
+## ViewStub使用
+
+### ViewStub 简介
+
+ViewStub 是一个轻量级的 View,用于延迟加载布局。只有在调用 `inflate()` 时才会加载实际布局。
+
+### 使用场景
+
+1. **条件显示**:根据条件决定是否显示某个布局
+2. **延迟加载**:减少初始布局复杂度
+3. **性能优化**:避免加载不必要的布局
+
+### 使用示例
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+```java
+public class MyActivity extends AppCompatActivity {
+ private ViewStub mViewStub;
+ private View mInflatedView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ mViewStub = findViewById(R.id.view_stub);
+
+ // 需要时才加载
+ if (shouldShowHeavyLayout()) {
+ mInflatedView = mViewStub.inflate();
+ // 或者
+ // mViewStub.setVisibility(View.VISIBLE);
+ // mInflatedView = mViewStub.getRootView();
+ }
+ }
+
+ private boolean shouldShowHeavyLayout() {
+ // 判断条件
+ return true;
+ }
+}
+```
+
+### ViewStub 注意事项
+
+1. **只能 inflate 一次**:inflate 后 ViewStub 会被替换为实际布局
+2. **必须设置 layout 属性**:指定要加载的布局
+3. **不支持 merge 标签**:ViewStub 的 layout 不能使用 merge
+
+---
+
+## Merge标签
+
+### Merge 简介
+
+`` 标签用于消除布局层级,将子 View 直接添加到父布局中。
+
+### 使用场景
+
+1. **Include 布局**:消除 include 带来的额外层级
+2. **自定义 View**:减少自定义 View 的层级
+
+### 使用示例
+
+#### 场景1:Include 布局
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+#### 场景2:自定义 View
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```java
+public class CustomView extends LinearLayout {
+ public CustomView(Context context) {
+ super(context);
+ LayoutInflater.from(context).inflate(R.layout.custom_view, this, true);
+ }
+}
+```
+
+### Merge 注意事项
+
+1. **必须指定根布局类型**:merge 本身不是 View,需要知道添加到什么类型的父布局
+2. **不能单独使用**:必须作为 include 或自定义 View 的根布局
+3. **属性设置**:merge 标签不能设置属性,属性需要在 include 或父布局中设置
+
+---
+
+## Include标签
+
+### Include 简介
+
+`` 标签用于复用布局,避免重复编写相同的布局代码。
+
+### 使用示例
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Include 覆盖属性
+
+```xml
+
+
+```
+
+### Include 注意事项
+
+1. **必须指定 layout 属性**:指定要包含的布局文件
+2. **可以覆盖属性**:可以覆盖被包含布局根 View 的 layout_* 属性
+3. **ID 冲突**:如果 include 和被包含布局都设置了 id,include 的 id 会覆盖
+
+---
+
+## ConstraintLayout
+
+### ConstraintLayout 简介
+
+ConstraintLayout 是 Android 官方推荐的布局,可以创建扁平化的布局结构,减少嵌套。
+
+### 优势
+
+1. **扁平化结构**:减少布局层级
+2. **性能好**:测量和布局速度快
+3. **功能强大**:支持链、屏障、引导线等高级功能
+4. **可视化编辑**:Android Studio 支持可视化编辑
+
+### 基本使用
+
+```xml
+
+
+
+
+
+
+
+```
+
+### 常用约束
+
+```xml
+
+app:layout_constraintTop_toTopOf="parent"
+app:layout_constraintTop_toBottomOf="@id/view"
+app:layout_constraintStart_toStartOf="parent"
+app:layout_constraintEnd_toEndOf="parent"
+
+
+android:layout_margin="16dp"
+android:layout_marginStart="8dp"
+
+
+android:layout_width="0dp"
+app:layout_constraintWidth_default="wrap"
+app:layout_constraintWidth_min="100dp"
+app:layout_constraintWidth_max="200dp"
+
+
+app:layout_constraintDimensionRatio="16:9"
+
+
+app:layout_constraintHorizontal_weight="1"
+app:layout_constraintVertical_weight="1"
+```
+
+### 链(Chain)
+
+```xml
+
+
+
+
+
+```
+
+### 屏障(Barrier)
+
+```xml
+
+
+
+```
+
+### 引导线(Guideline)
+
+```xml
+
+
+
+```
+
+---
+
+## 布局优化工具
+
+### 1. Layout Inspector
+
+- Android Studio -> Tools -> Layout Inspector
+- 实时查看布局层级
+- 查看 View 属性
+- 分析布局性能
+
+### 2. Hierarchy Viewer
+
+```bash
+# 启用 View Server
+adb shell service call window 3 i32 4939
+
+# 打开 Hierarchy Viewer
+# Tools -> Android -> Android Device Monitor
+```
+
+### 3. Lint 检查
+
+```bash
+# 运行 Lint 检查
+./gradlew lint
+
+# 检查布局问题
+# - 嵌套过深
+# - 无用的 ViewGroup
+# - 硬编码尺寸
+```
+
+### 4. Systrace
+
+```bash
+# 分析布局性能
+python systrace.py -t 10 -o trace.html gfx view
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 如何优化布局性能?
+
+**答案:**
+1. **减少布局层级**:使用 ConstraintLayout 替代嵌套布局
+2. **使用 ViewStub**:延迟加载不必要的布局
+3. **使用 Merge 标签**:消除不必要的布局层级
+4. **使用 Include 标签**:复用布局代码
+5. **避免过度绘制**:减少背景色、移除不必要的 View
+
+### Q2: ViewStub 的作用是什么?
+
+**答案:**
+- ViewStub 是一个轻量级的 View,用于延迟加载布局
+- 只有在调用 `inflate()` 时才会加载实际布局
+- 可以减少初始布局的复杂度,提升启动速度
+- 适合用于条件显示的布局
+
+### Q3: Merge 标签的使用场景?
+
+**答案:**
+1. **Include 布局**:消除 include 带来的额外层级
+2. **自定义 View**:减少自定义 View 的层级
+3. **减少嵌套**:将子 View 直接添加到父布局中
+
+### Q4: ConstraintLayout 的优势?
+
+**答案:**
+1. **扁平化结构**:减少布局层级,提升性能
+2. **功能强大**:支持链、屏障、引导线等高级功能
+3. **可视化编辑**:Android Studio 支持可视化编辑
+4. **性能好**:测量和布局速度快
+
+### Q5: 如何减少布局层级?
+
+**答案:**
+1. 使用 ConstraintLayout 替代嵌套 LinearLayout/RelativeLayout
+2. 使用 Merge 标签消除不必要的层级
+3. 避免不必要的 ViewGroup
+4. 使用 RelativeLayout 替代嵌套 LinearLayout
+
+### Q6: Include 和 Merge 的区别?
+
+**答案:**
+- **Include**:用于复用布局,会创建一个新的 ViewGroup
+- **Merge**:用于消除布局层级,将子 View 直接添加到父布局中
+- **组合使用**:Include + Merge 可以复用布局且不增加层级
+
+### Q7: 如何分析布局性能?
+
+**答案:**
+1. 使用 Layout Inspector 查看布局层级
+2. 使用 Hierarchy Viewer 分析布局性能
+3. 使用 Systrace 分析布局绘制时间
+4. 使用 Lint 检查布局问题
+5. 代码中测量布局加载时间
+
+### Q8: 布局优化的最佳实践?
+
+**答案:**
+1. 减少布局层级,使用 ConstraintLayout
+2. 使用 ViewStub 延迟加载
+3. 使用 Merge 和 Include 复用布局
+4. 避免过度绘制
+5. 使用合适的 View 类型
+6. 避免在 onDraw 中创建对象
+7. 使用硬件加速
+
+---
+
+## 总结
+
+布局优化是 Android 性能优化的重要部分,主要从以下几个方面入手:
+
+1. **减少布局层级**:使用 ConstraintLayout、Merge 标签
+2. **延迟加载**:使用 ViewStub
+3. **复用布局**:使用 Include 标签
+4. **性能分析**:使用 Layout Inspector、Hierarchy Viewer、Systrace
+
+通过合理的布局优化,可以提升布局加载速度,减少内存占用,提升应用性能。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/性能优化/流畅度优化.md b/docs/android面试/性能优化/流畅度优化.md
new file mode 100644
index 0000000..02268c3
--- /dev/null
+++ b/docs/android面试/性能优化/流畅度优化.md
@@ -0,0 +1,535 @@
+# 流畅度优化
+
+## 目录
+- [卡顿原因分析](#卡顿原因分析)
+- [60fps保证](#60fps保证)
+- [VSYNC机制](#vsync机制)
+- [Choreographer](#choreographer)
+- [过度绘制优化](#过度绘制优化)
+- [流畅度优化工具](#流畅度优化工具)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 卡顿原因分析
+
+### 卡顿的定义
+
+卡顿是指界面渲染不流畅,帧率低于 60fps(每秒 60 帧),用户感知到画面不连续。
+
+### 卡顿的主要原因
+
+#### 1. 主线程阻塞
+
+```java
+// ❌ 错误示例:主线程执行耗时操作
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // 主线程执行耗时操作
+ loadDataFromDatabase(); // 阻塞主线程
+ processLargeImage(); // 阻塞主线程
+}
+
+// ✅ 正确做法:使用异步处理
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // 异步执行耗时操作
+ new Thread(() -> {
+ loadDataFromDatabase();
+ processLargeImage();
+
+ // 更新 UI 回到主线程
+ runOnUiThread(() -> {
+ updateUI();
+ });
+ }).start();
+}
+```
+
+#### 2. 布局复杂
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+#### 3. 过度绘制
+
+```java
+// ❌ 错误示例:多层背景
+
+
+
+
+
+
+// ✅ 正确做法:移除不必要的背景
+
+
+
+```
+
+#### 4. 频繁创建对象
+
+```java
+// ❌ 错误示例:在 onDraw 中创建对象
+@Override
+protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ Paint paint = new Paint(); // 每次绘制都创建新对象
+ canvas.drawText("Hello", 0, 0, paint);
+}
+
+// ✅ 正确做法:复用对象
+public class MyView extends View {
+ private Paint mPaint; // 复用 Paint 对象
+
+ public MyView(Context context) {
+ super(context);
+ mPaint = new Paint();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.drawText("Hello", 0, 0, mPaint);
+ }
+}
+```
+
+#### 5. 动画性能问题
+
+```java
+// ❌ 错误示例:使用 View 动画(在主线程)
+view.animate()
+ .translationX(100)
+ .setDuration(1000)
+ .start();
+
+// ✅ 正确做法:使用属性动画(硬件加速)
+ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 0, 100);
+animator.setDuration(1000);
+animator.start();
+```
+
+---
+
+## 60fps保证
+
+### 帧率计算
+
+```
+fps = 1000ms / 单帧耗时
+60fps = 1000ms / 16.67ms
+```
+
+### 保证 60fps 的要求
+
+1. **单帧耗时 < 16.67ms**
+2. **主线程不阻塞**
+3. **布局不复杂**
+4. **不过度绘制**
+5. **使用硬件加速**
+
+### 性能监控
+
+```java
+public class FrameMonitor {
+ private Choreographer choreographer;
+ private long lastFrameTime = 0;
+ private int frameCount = 0;
+ private long totalFrameTime = 0;
+
+ public void start() {
+ choreographer = Choreographer.getInstance();
+ choreographer.postFrameCallback(new Choreographer.FrameCallback() {
+ @Override
+ public void doFrame(long frameTimeNanos) {
+ if (lastFrameTime != 0) {
+ long frameTime = (frameTimeNanos - lastFrameTime) / 1_000_000; // 转换为毫秒
+ totalFrameTime += frameTime;
+ frameCount++;
+
+ if (frameTime > 16.67) {
+ Log.w("FrameMonitor", "Frame dropped: " + frameTime + "ms");
+ }
+ }
+ lastFrameTime = frameTimeNanos;
+ choreographer.postFrameCallback(this);
+ }
+ });
+ }
+
+ public float getAverageFps() {
+ if (frameCount == 0) {
+ return 0;
+ }
+ float averageFrameTime = totalFrameTime / (float) frameCount;
+ return 1000.0f / averageFrameTime;
+ }
+}
+```
+
+---
+
+## VSYNC机制
+
+### VSYNC 简介
+
+VSYNC(Vertical Synchronization)是垂直同步信号,用于同步屏幕刷新和 GPU 渲染。
+
+### VSYNC 工作原理
+
+```
+时间轴:
+0ms 16.67ms 33.34ms 50ms
+|--------|--------|--------|
+ VSYNC VSYNC VSYNC
+```
+
+1. **VSYNC 信号触发**:每 16.67ms 触发一次
+2. **CPU 处理**:处理输入事件、测量布局
+3. **GPU 渲染**:渲染帧到缓冲区
+4. **屏幕显示**:显示缓冲区内容
+
+### VSYNC 优化
+
+```java
+// 使用 VSYNC 同步动画
+view.postOnAnimation(() -> {
+ // 在下一个 VSYNC 执行
+ updateAnimation();
+});
+```
+
+---
+
+## Choreographer
+
+### Choreographer 简介
+
+Choreographer 是 Android 4.1+ 引入的帧调度器,用于协调动画、输入和绘制。
+
+### Choreographer 工作原理
+
+```java
+public class Choreographer {
+ // 三种回调类型
+ public static final int CALLBACK_INPUT = 0; // 输入事件
+ public static final int CALLBACK_ANIMATION = 1; // 动画
+ public static final int CALLBACK_TRAVERSAL = 2; // 绘制
+
+ // 执行顺序
+ // 1. CALLBACK_INPUT:处理输入事件
+ // 2. CALLBACK_ANIMATION:执行动画
+ // 3. CALLBACK_TRAVERSAL:执行绘制
+}
+```
+
+### Choreographer 使用
+
+```java
+// 在下一个 VSYNC 执行
+Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
+ @Override
+ public void doFrame(long frameTimeNanos) {
+ // 执行操作
+ updateUI();
+
+ // 继续下一帧
+ Choreographer.getInstance().postFrameCallback(this);
+ }
+});
+
+// 延迟执行
+Choreographer.getInstance().postFrameCallbackDelayed(callback, delayMillis);
+```
+
+### 帧率监控
+
+```java
+public class FrameRateMonitor {
+ private Choreographer choreographer;
+ private long lastFrameTime = 0;
+ private int droppedFrames = 0;
+
+ public void start() {
+ choreographer = Choreographer.getInstance();
+ choreographer.postFrameCallback(new Choreographer.FrameCallback() {
+ @Override
+ public void doFrame(long frameTimeNanos) {
+ if (lastFrameTime != 0) {
+ long frameTime = (frameTimeNanos - lastFrameTime) / 1_000_000;
+ if (frameTime > 16.67) {
+ droppedFrames += (int) (frameTime / 16.67) - 1;
+ Log.w("FrameRate", "Dropped frames: " + droppedFrames);
+ }
+ }
+ lastFrameTime = frameTimeNanos;
+ choreographer.postFrameCallback(this);
+ }
+ });
+ }
+}
+```
+
+---
+
+## 过度绘制优化
+
+### 什么是过度绘制?
+
+过度绘制是指同一像素被绘制多次,浪费 GPU 资源。
+
+### 过度绘制检测
+
+#### 1. 开发者选项
+
+```
+设置 -> 开发者选项 -> 调试 GPU 过度绘制 -> 显示过度绘制区域
+```
+
+- **蓝色**:绘制 1 次(正常)
+- **绿色**:绘制 2 次(可接受)
+- **浅红色**:绘制 3 次(需要优化)
+- **深红色**:绘制 4 次以上(必须优化)
+
+#### 2. 代码检测
+
+```java
+// 启用过度绘制检测
+View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+```
+
+### 过度绘制优化方法
+
+#### 1. 移除不必要的背景
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+#### 2. 使用 clipRect
+
+```java
+@Override
+protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // 裁剪绘制区域
+ canvas.clipRect(0, 0, width, height);
+
+ // 只绘制可见区域
+ drawContent(canvas);
+}
+```
+
+#### 3. 使用 ViewStub
+
+```xml
+
+
+```
+
+#### 4. 优化自定义 View
+
+```java
+@Override
+protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // 只绘制可见区域
+ if (shouldDraw()) {
+ drawContent(canvas);
+ }
+}
+```
+
+---
+
+## 流畅度优化工具
+
+### 1. GPU 渲染模式分析
+
+```
+设置 -> 开发者选项 -> GPU 渲染模式分析 -> 在屏幕上显示为条形图
+```
+
+- **绿色线**:16.67ms 基准线
+- **红色条**:超过 16.67ms,表示卡顿
+
+### 2. Systrace/Perfetto
+
+```bash
+# 分析流畅度
+python systrace.py -t 10 -o trace.html gfx view input
+```
+
+### 3. Android Studio Profiler
+
+- CPU Profiler:分析 CPU 使用
+- Memory Profiler:分析内存使用
+- Network Profiler:分析网络请求
+
+### 4. Layout Inspector
+
+- 查看布局层级
+- 分析布局性能
+- 查看 View 属性
+
+### 5. 自定义监控工具
+
+```java
+public class PerformanceMonitor {
+ private Handler handler = new Handler(Looper.getMainLooper());
+ private Runnable monitorRunnable = new Runnable() {
+ @Override
+ public void run() {
+ // 监控主线程性能
+ long startTime = System.currentTimeMillis();
+ handler.post(() -> {
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ if (duration > 16) {
+ Log.w("Performance", "Main thread blocked: " + duration + "ms");
+ }
+ });
+ handler.postDelayed(this, 100);
+ }
+ };
+
+ public void start() {
+ handler.post(monitorRunnable);
+ }
+
+ public void stop() {
+ handler.removeCallbacks(monitorRunnable);
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 如何保证 60fps?
+
+**答案:**
+1. **单帧耗时 < 16.67ms**
+2. **主线程不阻塞**:避免在主线程执行耗时操作
+3. **布局优化**:减少布局层级,使用 ConstraintLayout
+4. **避免过度绘制**:移除不必要的背景
+5. **使用硬件加速**:启用硬件加速
+6. **优化动画**:使用属性动画,避免 View 动画
+
+### Q2: 什么是 VSYNC?
+
+**答案:**
+- VSYNC(Vertical Synchronization)是垂直同步信号
+- 用于同步屏幕刷新和 GPU 渲染
+- 每 16.67ms 触发一次(60fps)
+- 保证画面不撕裂,流畅显示
+
+### Q3: Choreographer 的作用?
+
+**答案:**
+- Choreographer 是帧调度器
+- 协调输入事件、动画、绘制
+- 按顺序执行:输入 -> 动画 -> 绘制
+- 保证在 VSYNC 信号时执行
+
+### Q4: 如何检测卡顿?
+
+**答案:**
+1. **GPU 渲染模式分析**:查看条形图
+2. **Systrace/Perfetto**:分析系统性能
+3. **Android Studio Profiler**:分析 CPU、内存
+4. **自定义监控**:监控帧率、主线程阻塞
+5. **开发者选项**:启用过度绘制检测
+
+### Q5: 过度绘制如何优化?
+
+**答案:**
+1. **移除不必要的背景**:减少背景层数
+2. **使用 clipRect**:只绘制可见区域
+3. **使用 ViewStub**:延迟加载布局
+4. **优化自定义 View**:只绘制必要内容
+5. **使用硬件加速**:提升绘制性能
+
+### Q6: 主线程阻塞的原因和解决方案?
+
+**答案:**
+- **原因**:
+ 1. 执行耗时操作(网络请求、数据库操作)
+ 2. 复杂计算
+ 3. 同步等待
+
+- **解决方案**:
+ 1. 使用异步处理(线程、协程)
+ 2. 使用 Handler 切换到后台线程
+ 3. 使用 AsyncTask、RxJava 等框架
+ 4. 优化算法,减少计算时间
+
+### Q7: 流畅度优化的最佳实践?
+
+**答案:**
+1. **主线程优化**:避免阻塞,使用异步处理
+2. **布局优化**:减少层级,使用 ConstraintLayout
+3. **绘制优化**:避免过度绘制,使用硬件加速
+4. **动画优化**:使用属性动画,避免 View 动画
+5. **监控性能**:使用工具检测,及时发现问题
+
+---
+
+## 总结
+
+流畅度优化是 Android 性能优化的重要部分,主要从以下几个方面入手:
+
+1. **保证 60fps**:单帧耗时 < 16.67ms
+2. **主线程优化**:避免阻塞,使用异步处理
+3. **布局优化**:减少层级,使用 ConstraintLayout
+4. **绘制优化**:避免过度绘制,使用硬件加速
+5. **VSYNC 机制**:理解 VSYNC 和 Choreographer
+6. **性能监控**:使用工具检测,及时发现问题
+
+通过合理的流畅度优化,可以提升用户体验,让应用运行更加流畅。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/性能优化/电量优化.md b/docs/android面试/性能优化/电量优化.md
new file mode 100644
index 0000000..dc440b3
--- /dev/null
+++ b/docs/android面试/性能优化/电量优化.md
@@ -0,0 +1,619 @@
+# 电量优化
+
+## 目录
+- [电量消耗分析](#电量消耗分析)
+- [WakeLock使用](#wakelock使用)
+- [JobScheduler](#jobscheduler)
+- [WorkManager](#workmanager)
+- [后台任务优化](#后台任务优化)
+- [电量优化工具](#电量优化工具)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 电量消耗分析
+
+### 电量消耗主要来源
+
+1. **CPU**:频繁计算、长时间运行
+2. **网络**:频繁请求、大数据传输
+3. **定位**:GPS、网络定位
+4. **屏幕**:高亮度、长时间亮屏
+5. **传感器**:加速度计、陀螺仪等
+6. **WakeLock**:阻止系统休眠
+
+### 电量消耗分析工具
+
+#### 1. Battery Historian
+
+```bash
+# 收集电池数据
+adb shell dumpsys batterystats --reset
+# 使用应用一段时间
+adb shell dumpsys batterystats > batterystats.txt
+
+# 生成报告
+python historian.py batterystats.txt > battery.html
+```
+
+#### 2. Battery Profiler
+
+- Android Studio -> View -> Tool Windows -> Profiler
+- 实时查看电量消耗
+- 分析电量消耗趋势
+- 查看唤醒锁使用情况
+
+#### 3. adb 命令
+
+```bash
+# 查看电量信息
+adb shell dumpsys battery
+
+# 查看电量统计
+adb shell dumpsys batterystats
+
+# 查看唤醒锁
+adb shell dumpsys power
+```
+
+---
+
+## WakeLock使用
+
+### WakeLock 简介
+
+WakeLock 用于阻止系统进入休眠状态,保持 CPU 运行或屏幕亮起。
+
+### WakeLock 类型
+
+```java
+// PARTIAL_WAKE_LOCK:保持 CPU 运行,屏幕可以关闭
+PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock"
+);
+
+// SCREEN_DIM_WAKE_LOCK:保持屏幕变暗,CPU 运行(已废弃)
+// SCREEN_BRIGHT_WAKE_LOCK:保持屏幕高亮,CPU 运行(已废弃)
+// FULL_WAKE_LOCK:保持屏幕高亮,键盘背光,CPU 运行(已废弃)
+
+// ACQUIRE_CAUSES_WAKEUP:获取时立即唤醒屏幕
+// ON_AFTER_RELEASE:释放后保持屏幕亮起一段时间
+```
+
+### WakeLock 使用示例
+
+```java
+public class WakeLockManager {
+ private PowerManager powerManager;
+ private PowerManager.WakeLock wakeLock;
+
+ public WakeLockManager(Context context) {
+ powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ wakeLock = powerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "MyApp::WakeLock"
+ );
+ }
+
+ public void acquire() {
+ if (!wakeLock.isHeld()) {
+ wakeLock.acquire();
+ }
+ }
+
+ public void release() {
+ if (wakeLock.isHeld()) {
+ wakeLock.release();
+ }
+ }
+
+ public void acquire(long timeout) {
+ if (!wakeLock.isHeld()) {
+ wakeLock.acquire(timeout); // 超时自动释放
+ }
+ }
+}
+
+// 使用
+WakeLockManager manager = new WakeLockManager(context);
+manager.acquire();
+// 执行需要保持 CPU 运行的任务
+manager.release();
+```
+
+### WakeLock 注意事项
+
+```java
+// ❌ 错误示例:忘记释放 WakeLock
+public void doWork() {
+ wakeLock.acquire();
+ // 如果这里抛出异常,WakeLock 不会被释放
+ doSomething();
+ wakeLock.release();
+}
+
+// ✅ 正确做法:使用 try-finally
+public void doWork() {
+ wakeLock.acquire();
+ try {
+ doSomething();
+ } finally {
+ wakeLock.release();
+ }
+}
+
+// ✅ 使用超时自动释放
+wakeLock.acquire(10 * 60 * 1000L); // 10分钟后自动释放
+```
+
+### WakeLock 最佳实践
+
+1. **及时释放**:使用完毕后立即释放
+2. **使用超时**:设置超时时间,避免忘记释放
+3. **最小化使用**:只在必要时使用,尽量减少使用时间
+4. **使用替代方案**:优先使用 JobScheduler、WorkManager
+
+---
+
+## JobScheduler
+
+### JobScheduler 简介
+
+JobScheduler 是 Android 5.0+ 提供的任务调度框架,可以在合适的时机执行任务,节省电量。
+
+### JobScheduler 优势
+
+1. **智能调度**:系统选择最佳时机执行
+2. **批量执行**:合并多个任务一起执行
+3. **条件触发**:满足条件时才执行
+4. **电量友好**:减少电量消耗
+
+### JobScheduler 使用示例
+
+```java
+public class MyJobService extends JobService {
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ // 执行任务(在后台线程)
+ new Thread(() -> {
+ // 执行任务
+ doWork();
+
+ // 任务完成
+ jobFinished(params, false);
+ }).start();
+
+ return true; // 返回 true 表示任务在后台执行
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ // 任务被取消
+ return false; // 返回 false 表示任务不需要重新调度
+ }
+
+ private void doWork() {
+ // 执行具体任务
+ }
+}
+```
+
+```java
+public class JobSchedulerHelper {
+ private JobScheduler jobScheduler;
+
+ public JobSchedulerHelper(Context context) {
+ jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ }
+
+ public void scheduleJob() {
+ JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(context, MyJobService.class))
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) // 需要网络
+ .setRequiresCharging(false) // 不需要充电
+ .setRequiresDeviceIdle(false) // 不需要设备空闲
+ .setPeriodic(15 * 60 * 1000) // 每15分钟执行一次
+ .setPersisted(true) // 持久化,重启后仍然有效
+ .build();
+
+ jobScheduler.schedule(jobInfo);
+ }
+
+ public void cancelJob(int jobId) {
+ jobScheduler.cancel(jobId);
+ }
+
+ public void cancelAllJobs() {
+ jobScheduler.cancelAll();
+ }
+}
+```
+
+### JobScheduler 条件
+
+```java
+JobInfo jobInfo = new JobInfo.Builder(1, componentName)
+ // 网络条件
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE) // 不需要网络
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) // 任何网络
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 非计费网络(WiFi)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING) // 非漫游网络
+
+ // 充电条件
+ .setRequiresCharging(true) // 需要充电
+
+ // 设备空闲条件
+ .setRequiresDeviceIdle(true) // 需要设备空闲
+
+ // 存储条件
+ .setRequiresStorageNotLow(true) // 存储空间充足
+
+ // 电池条件
+ .setRequiresBatteryNotLow(true) // 电池电量充足
+
+ // 执行时间
+ .setMinimumLatency(1000) // 最小延迟1秒
+ .setOverrideDeadline(5000) // 最晚5秒后执行
+ .setPeriodic(15 * 60 * 1000) // 每15分钟执行一次
+
+ .build();
+```
+
+---
+
+## WorkManager
+
+### WorkManager 简介
+
+WorkManager 是 Android Jetpack 提供的任务调度框架,兼容 Android 4.0+,是 JobScheduler、Firebase JobDispatcher、AlarmManager 的统一封装。
+
+### WorkManager 优势
+
+1. **向后兼容**:兼容所有 Android 版本
+2. **智能调度**:自动选择最佳调度方式
+3. **链式任务**:支持任务链和任务组
+4. **约束条件**:支持多种约束条件
+5. **持久化**:任务持久化,应用重启后仍然有效
+
+### WorkManager 使用示例
+
+#### 1. 定义 Worker
+
+```java
+public class MyWorker extends Worker {
+ public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ super(context, workerParams);
+ }
+
+ @NonNull
+ @Override
+ public Result doWork() {
+ // 执行任务
+ try {
+ doSomething();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.retry(); // 重试
+ // 或
+ // return Result.failure(); // 失败
+ }
+ }
+
+ private void doSomething() {
+ // 执行具体任务
+ }
+}
+```
+
+#### 2. 创建 WorkRequest
+
+```java
+// 一次性任务
+OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
+ .setConstraints(constraints)
+ .setInitialDelay(10, TimeUnit.SECONDS)
+ .addTag("my_tag")
+ .build();
+
+// 周期性任务
+PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(
+ MyWorker.class,
+ 15, TimeUnit.MINUTES
+).build();
+```
+
+#### 3. 设置约束条件
+
+```java
+Constraints constraints = new Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED) // 需要网络连接
+ .setRequiresCharging(true) // 需要充电
+ .setRequiresDeviceIdle(true) // 需要设备空闲
+ .setRequiresBatteryNotLow(true) // 电池电量充足
+ .setRequiresStorageNotLow(true) // 存储空间充足
+ .build();
+```
+
+#### 4. 提交任务
+
+```java
+WorkManager workManager = WorkManager.getInstance(context);
+
+// 提交一次性任务
+workManager.enqueue(workRequest);
+
+// 提交周期性任务
+workManager.enqueue(periodicWorkRequest);
+
+// 取消任务
+workManager.cancelWorkById(workRequest.getId());
+workManager.cancelAllWorkByTag("my_tag");
+workManager.cancelAllWork();
+```
+
+#### 5. 观察任务状态
+
+```java
+workManager.getWorkInfoByIdLiveData(workRequest.getId())
+ .observe(lifecycleOwner, workInfo -> {
+ if (workInfo != null) {
+ WorkInfo.State state = workInfo.getState();
+ if (state == WorkInfo.State.SUCCEEDED) {
+ // 任务成功
+ } else if (state == WorkInfo.State.FAILED) {
+ // 任务失败
+ }
+ }
+ });
+```
+
+#### 6. 链式任务
+
+```java
+// 顺序执行
+WorkManager workManager = WorkManager.getInstance(context);
+workManager
+ .beginWith(workRequest1)
+ .then(workRequest2)
+ .then(workRequest3)
+ .enqueue();
+
+// 并行执行
+workManager
+ .beginWith(workRequest1, workRequest2)
+ .then(workRequest3)
+ .enqueue();
+```
+
+---
+
+## 后台任务优化
+
+### 1. 减少后台任务频率
+
+```java
+// ❌ 错误示例:频繁执行后台任务
+Timer timer = new Timer();
+timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ syncData(); // 每分钟同步一次
+ }
+}, 0, 60 * 1000);
+
+// ✅ 正确做法:使用 WorkManager 智能调度
+PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
+ SyncWorker.class,
+ 15, TimeUnit.MINUTES
+).build();
+WorkManager.getInstance(context).enqueue(workRequest);
+```
+
+### 2. 批量处理任务
+
+```java
+// ❌ 错误示例:逐个处理
+for (Item item : items) {
+ processItem(item); // 每个任务都唤醒设备
+}
+
+// ✅ 正确做法:批量处理
+List- batch = new ArrayList<>();
+for (Item item : items) {
+ batch.add(item);
+ if (batch.size() >= 10) {
+ processBatch(batch); // 批量处理
+ batch.clear();
+ }
+}
+```
+
+### 3. 使用前台服务
+
+```java
+// 对于需要长时间运行的任务,使用前台服务
+public class MyForegroundService extends Service {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Notification notification = createNotification();
+ startForeground(1, notification);
+ }
+
+ private Notification createNotification() {
+ return new NotificationCompat.Builder(this, CHANNEL_ID)
+ .setContentTitle("正在运行")
+ .setContentText("任务进行中")
+ .setSmallIcon(R.drawable.ic_notification)
+ .build();
+ }
+}
+```
+
+### 4. 避免长时间运行
+
+```java
+// ❌ 错误示例:长时间运行
+public void doWork() {
+ while (true) {
+ processData();
+ Thread.sleep(1000);
+ }
+}
+
+// ✅ 正确做法:使用 WorkManager 或 JobScheduler
+// 让系统决定何时执行任务
+```
+
+### 5. 优化网络请求
+
+```java
+// ❌ 错误示例:频繁请求
+Timer timer = new Timer();
+timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ api.getData().enqueue(callback); // 每分钟请求一次
+ }
+}, 0, 60 * 1000);
+
+// ✅ 正确做法:使用推送或智能调度
+// 使用 FCM 推送通知,或使用 WorkManager 在合适时机请求
+```
+
+---
+
+## 电量优化工具
+
+### 1. Battery Historian
+
+```bash
+# 收集数据
+adb shell dumpsys batterystats --reset
+# 使用应用
+adb shell dumpsys batterystats > batterystats.txt
+
+# 生成报告
+python historian.py batterystats.txt > battery.html
+```
+
+### 2. Battery Profiler
+
+- Android Studio -> View -> Tool Windows -> Profiler
+- 实时查看电量消耗
+- 分析唤醒锁使用
+- 查看 CPU 使用情况
+
+### 3. adb 命令
+
+```bash
+# 查看电量信息
+adb shell dumpsys battery
+
+# 查看唤醒锁
+adb shell dumpsys power
+
+# 查看电量统计
+adb shell dumpsys batterystats
+```
+
+### 4. Doze 模式测试
+
+```bash
+# 进入 Doze 模式
+adb shell dumpsys deviceidle force-idle
+
+# 退出 Doze 模式
+adb shell dumpsys deviceidle unforce
+
+# 查看 Doze 状态
+adb shell dumpsys deviceidle
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 如何优化应用电量消耗?
+
+**答案:**
+1. **减少后台任务**:使用 JobScheduler、WorkManager 智能调度
+2. **优化网络请求**:减少请求频率、批量处理
+3. **合理使用 WakeLock**:及时释放、使用超时
+4. **优化定位**:使用缓存、降低定位频率
+5. **优化屏幕**:降低亮度、及时关闭屏幕
+6. **优化 CPU**:减少计算、使用异步处理
+
+### Q2: WakeLock 的作用和使用注意事项?
+
+**答案:**
+- **作用**:阻止系统进入休眠状态
+- **类型**:PARTIAL_WAKE_LOCK(保持 CPU)、SCREEN_BRIGHT_WAKE_LOCK(保持屏幕)
+- **注意事项**:
+ 1. 及时释放,避免忘记释放
+ 2. 使用超时,设置自动释放时间
+ 3. 最小化使用,只在必要时使用
+ 4. 优先使用 JobScheduler、WorkManager
+
+### Q3: JobScheduler 和 WorkManager 的区别?
+
+**答案:**
+- **JobScheduler**:
+ - Android 5.0+ 支持
+ - 系统级 API
+ - 功能相对简单
+
+- **WorkManager**:
+ - Android 4.0+ 支持(向后兼容)
+ - Jetpack 组件
+ - 功能更强大,支持链式任务、任务组
+ - 自动选择最佳调度方式
+
+### Q4: 如何分析应用电量消耗?
+
+**答案:**
+1. **Battery Historian**:生成详细的电量消耗报告
+2. **Battery Profiler**:实时查看电量消耗
+3. **adb 命令**:查看电量统计、唤醒锁使用
+4. **系统设置**:查看应用电量使用情况
+
+### Q5: Doze 模式对应用的影响?
+
+**答案:**
+- **Doze 模式**:Android 6.0+ 的省电模式
+- **影响**:
+ 1. 限制网络访问
+ 2. 延迟后台任务
+ 3. 限制唤醒锁
+- **应对**:
+ 1. 使用 WorkManager 或 JobScheduler
+ 2. 使用前台服务(重要任务)
+ 3. 使用 FCM 高优先级消息
+
+### Q6: 后台任务优化的最佳实践?
+
+**答案:**
+1. 使用 WorkManager 或 JobScheduler 智能调度
+2. 减少任务执行频率
+3. 批量处理任务
+4. 使用约束条件(网络、充电等)
+5. 避免长时间运行的任务
+6. 使用前台服务(重要任务)
+
+---
+
+## 总结
+
+电量优化是 Android 性能优化的重要部分,主要从以下几个方面入手:
+
+1. **减少后台任务**:使用智能调度框架
+2. **优化网络请求**:减少频率、批量处理
+3. **合理使用 WakeLock**:及时释放、最小化使用
+4. **使用约束条件**:只在满足条件时执行任务
+5. **监控电量消耗**:使用工具分析电量使用情况
+
+通过合理的电量优化,可以延长设备电池续航时间,提升用户体验。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/性能优化/网络优化.md b/docs/android面试/性能优化/网络优化.md
new file mode 100644
index 0000000..0df3b21
--- /dev/null
+++ b/docs/android面试/性能优化/网络优化.md
@@ -0,0 +1,722 @@
+# 网络优化
+
+## 目录
+- [网络请求优化](#网络请求优化)
+- [图片加载优化](#图片加载优化)
+- [数据压缩](#数据压缩)
+- [缓存策略](#缓存策略)
+- [网络监控](#网络监控)
+- [网络优化工具](#网络优化工具)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 网络请求优化
+
+### 1. 请求合并
+
+#### 问题:频繁请求
+```java
+// ❌ 错误示例:频繁请求
+for (int i = 0; i < 100; i++) {
+ api.getUserInfo(i).enqueue(callback);
+}
+```
+
+#### 解决方案:批量请求
+```java
+// ✅ 正确做法:批量请求
+List userIds = new ArrayList<>();
+for (int i = 0; i < 100; i++) {
+ userIds.add(i);
+}
+api.getBatchUserInfo(userIds).enqueue(callback);
+```
+
+### 2. 请求去重
+
+```java
+public class RequestDeduplicator {
+ private final Map pendingRequests = new ConcurrentHashMap<>();
+
+ public void execute(String key, Call call, Callback callback) {
+ Call existingCall = (Call) pendingRequests.get(key);
+ if (existingCall != null) {
+ // 已有相同请求,取消新请求
+ call.cancel();
+ return;
+ }
+
+ pendingRequests.put(key, call);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ pendingRequests.remove(key);
+ callback.onResponse(call, response);
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ pendingRequests.remove(key);
+ callback.onFailure(call, t);
+ }
+ });
+ }
+}
+```
+
+### 3. 请求优先级
+
+```java
+public class PriorityInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+
+ // 根据优先级设置
+ int priority = request.header("Priority") != null
+ ? Integer.parseInt(request.header("Priority"))
+ : 0;
+
+ // 调整请求优先级
+ if (priority > 0) {
+ // 高优先级请求优先处理
+ }
+
+ return chain.proceed(request);
+ }
+}
+```
+
+### 4. 请求重试
+
+```java
+public class RetryInterceptor implements Interceptor {
+ private int maxRetries;
+
+ public RetryInterceptor(int maxRetries) {
+ this.maxRetries = maxRetries;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ Response response = null;
+ IOException exception = null;
+
+ for (int i = 0; i <= maxRetries; i++) {
+ try {
+ response = chain.proceed(request);
+ if (response.isSuccessful()) {
+ return response;
+ }
+ } catch (IOException e) {
+ exception = e;
+ if (i == maxRetries) {
+ throw e;
+ }
+ }
+
+ // 等待后重试
+ try {
+ Thread.sleep(1000 * (i + 1));
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ throw exception;
+ }
+}
+```
+
+### 5. 连接池优化
+
+```java
+OkHttpClient client = new OkHttpClient.Builder()
+ .connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES))
+ .build();
+```
+
+### 6. 超时设置
+
+```java
+OkHttpClient client = new OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .writeTimeout(30, TimeUnit.SECONDS)
+ .build();
+```
+
+---
+
+## 图片加载优化
+
+### 1. 使用图片加载库
+
+```java
+// Glide:自动缓存、压缩、内存管理
+Glide.with(context)
+ .load(url)
+ .placeholder(R.drawable.placeholder)
+ .error(R.drawable.error)
+ .into(imageView);
+
+// 指定尺寸
+Glide.with(context)
+ .load(url)
+ .override(200, 200)
+ .into(imageView);
+```
+
+### 2. 图片压缩
+
+```java
+public Bitmap compressImage(Bitmap bitmap, int maxWidth, int maxHeight, int quality) {
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+
+ float scale = Math.min((float) maxWidth / width, (float) maxHeight / height);
+ if (scale < 1.0f) {
+ int newWidth = Math.round(width * scale);
+ int newHeight = Math.round(height * scale);
+ bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
+ byte[] data = baos.toByteArray();
+
+ return BitmapFactory.decodeByteArray(data, 0, data.length);
+}
+```
+
+### 3. 使用 WebP 格式
+
+```java
+// WebP 格式压缩率高
+Glide.with(context)
+ .load(url)
+ .format(DecodeFormat.PREFER_WEBP)
+ .into(imageView);
+```
+
+### 4. 懒加载
+
+```java
+public class LazyLoadImageView extends ImageView {
+ private String imageUrl;
+
+ public void setImageUrl(String url) {
+ this.imageUrl = url;
+ loadImage();
+ }
+
+ private void loadImage() {
+ if (isInViewport()) {
+ Glide.with(getContext())
+ .load(imageUrl)
+ .into(this);
+ }
+ }
+
+ private boolean isInViewport() {
+ Rect rect = new Rect();
+ getGlobalVisibleRect(rect);
+ return rect.width() > 0 && rect.height() > 0;
+ }
+}
+```
+
+### 5. 预加载
+
+```java
+// 预加载图片到缓存
+Glide.with(context)
+ .load(url)
+ .preload();
+
+// 预加载并获取 Bitmap
+Glide.with(context)
+ .asBitmap()
+ .load(url)
+ .into(new SimpleTarget() {
+ @Override
+ public void onResourceReady(Bitmap resource, Transition super Bitmap> transition) {
+ // 预加载完成
+ }
+ });
+```
+
+---
+
+## 数据压缩
+
+### 1. Gzip 压缩
+
+```java
+// 服务器端启用 Gzip
+// 客户端自动解压(OkHttp 支持)
+
+OkHttpClient client = new OkHttpClient.Builder()
+ .addInterceptor(new GzipRequestInterceptor())
+ .build();
+
+public class GzipRequestInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request originalRequest = chain.request();
+
+ if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
+ return chain.proceed(originalRequest);
+ }
+
+ Request compressedRequest = originalRequest.newBuilder()
+ .header("Content-Encoding", "gzip")
+ .method(originalRequest.method(), gzip(originalRequest.body()))
+ .build();
+
+ return chain.proceed(compressedRequest);
+ }
+
+ private RequestBody gzip(final RequestBody body) {
+ return new RequestBody() {
+ @Override
+ public MediaType contentType() {
+ return body.contentType();
+ }
+
+ @Override
+ public long contentLength() {
+ return -1;
+ }
+
+ @Override
+ public void writeTo(BufferedSink sink) throws IOException {
+ BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
+ body.writeTo(gzipSink);
+ gzipSink.close();
+ }
+ };
+ }
+}
+```
+
+### 2. 数据格式优化
+
+```java
+// 使用 Protobuf 替代 JSON
+// Protobuf 体积更小,解析更快
+
+// 使用 MessagePack 替代 JSON
+// MessagePack 是二进制格式,体积更小
+```
+
+### 3. 分页加载
+
+```java
+public class PagingHelper {
+ private int pageSize = 20;
+ private int currentPage = 0;
+ private boolean hasMore = true;
+
+ public void loadMore() {
+ if (!hasMore) {
+ return;
+ }
+
+ api.getData(currentPage, pageSize).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()) {
+ DataResponse data = response.body();
+ if (data.getItems().size() < pageSize) {
+ hasMore = false;
+ }
+ currentPage++;
+ // 处理数据
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ // 处理错误
+ }
+ });
+ }
+}
+```
+
+---
+
+## 缓存策略
+
+### 1. HTTP 缓存
+
+```java
+// 使用 OkHttp 缓存
+int cacheSize = 10 * 1024 * 1024; // 10MB
+Cache cache = new Cache(context.getCacheDir(), cacheSize);
+
+OkHttpClient client = new OkHttpClient.Builder()
+ .cache(cache)
+ .build();
+```
+
+### 2. 内存缓存
+
+```java
+public class MemoryCache {
+ private final LruCache cache;
+
+ public MemoryCache() {
+ int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
+ int cacheSize = maxMemory / 8;
+
+ cache = new LruCache(cacheSize) {
+ @Override
+ protected int sizeOf(String key, Bitmap bitmap) {
+ return bitmap.getByteCount() / 1024;
+ }
+ };
+ }
+
+ public Bitmap get(String key) {
+ return cache.get(key);
+ }
+
+ public void put(String key, Bitmap bitmap) {
+ cache.put(key, bitmap);
+ }
+}
+```
+
+### 3. 磁盘缓存
+
+```java
+public class DiskCache {
+ private final File cacheDir;
+
+ public DiskCache(Context context) {
+ cacheDir = new File(context.getCacheDir(), "images");
+ if (!cacheDir.exists()) {
+ cacheDir.mkdirs();
+ }
+ }
+
+ public void put(String key, Bitmap bitmap) {
+ File file = new File(cacheDir, key);
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
+ fos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Bitmap get(String key) {
+ File file = new File(cacheDir, key);
+ if (file.exists()) {
+ return BitmapFactory.decodeFile(file.getAbsolutePath());
+ }
+ return null;
+ }
+}
+```
+
+### 4. 三级缓存策略
+
+```java
+public class ImageLoader {
+ private MemoryCache memoryCache;
+ private DiskCache diskCache;
+ private NetworkLoader networkLoader;
+
+ public void load(String url, ImageView imageView) {
+ // 1. 检查内存缓存
+ Bitmap bitmap = memoryCache.get(url);
+ if (bitmap != null) {
+ imageView.setImageBitmap(bitmap);
+ return;
+ }
+
+ // 2. 检查磁盘缓存
+ bitmap = diskCache.get(url);
+ if (bitmap != null) {
+ imageView.setImageBitmap(bitmap);
+ memoryCache.put(url, bitmap);
+ return;
+ }
+
+ // 3. 从网络加载
+ networkLoader.load(url, new NetworkLoader.Callback() {
+ @Override
+ public void onSuccess(Bitmap bitmap) {
+ imageView.setImageBitmap(bitmap);
+ memoryCache.put(url, bitmap);
+ diskCache.put(url, bitmap);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ // 处理错误
+ }
+ });
+ }
+}
+```
+
+---
+
+## 网络监控
+
+### 1. 网络状态监听
+
+```java
+public class NetworkMonitor {
+ private ConnectivityManager connectivityManager;
+ private NetworkCallback networkCallback;
+
+ public void register(Context context) {
+ connectivityManager = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ networkCallback = new ConnectivityManager.NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ // 网络可用
+ }
+
+ @Override
+ public void onLost(Network network) {
+ // 网络不可用
+ }
+
+ @Override
+ public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+ // 网络能力变化
+ if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+ // WiFi 网络
+ } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+ // 移动网络
+ }
+ }
+ };
+
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build();
+
+ connectivityManager.registerNetworkCallback(request, networkCallback);
+ }
+
+ public void unregister() {
+ if (connectivityManager != null && networkCallback != null) {
+ connectivityManager.unregisterNetworkCallback(networkCallback);
+ }
+ }
+}
+```
+
+### 2. 请求监控
+
+```java
+public class NetworkMonitorInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ long startTime = System.currentTimeMillis();
+
+ Response response = chain.proceed(request);
+
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+
+ // 记录请求信息
+ Log.d("Network", String.format(
+ "Request: %s, Duration: %dms, Size: %d bytes",
+ request.url(),
+ duration,
+ response.body() != null ? response.body().contentLength() : 0
+ ));
+
+ return response;
+ }
+}
+```
+
+### 3. 网络质量检测
+
+```java
+public class NetworkQualityChecker {
+ public void checkNetworkQuality(Callback callback) {
+ long startTime = System.currentTimeMillis();
+
+ OkHttpClient client = new OkHttpClient();
+ Request request = new Request.Builder()
+ .url("https://www.google.com")
+ .build();
+
+ client.newCall(request).enqueue(new okhttp3.Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ long duration = System.currentTimeMillis() - startTime;
+ if (duration < 500) {
+ callback.onQuality(NetworkQuality.EXCELLENT);
+ } else if (duration < 1000) {
+ callback.onQuality(NetworkQuality.GOOD);
+ } else {
+ callback.onQuality(NetworkQuality.POOR);
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, IOException e) {
+ callback.onQuality(NetworkQuality.POOR);
+ }
+ });
+ }
+
+ enum NetworkQuality {
+ EXCELLENT, GOOD, POOR
+ }
+
+ interface Callback {
+ void onQuality(NetworkQuality quality);
+ }
+}
+```
+
+---
+
+## 网络优化工具
+
+### 1. Chrome DevTools
+
+- 查看网络请求
+- 分析请求时间
+- 查看请求大小
+- 检查缓存策略
+
+### 2. Charles/Fiddler
+
+- 抓包工具
+- 查看请求响应
+- 模拟慢网络
+- 修改请求响应
+
+### 3. Network Profiler
+
+- Android Studio -> View -> Tool Windows -> Profiler
+- 实时监控网络请求
+- 查看请求时间
+- 分析网络性能
+
+### 4. Stetho
+
+```java
+// 集成 Stetho
+dependencies {
+ implementation 'com.facebook.stetho:stetho:1.5.1'
+ implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1'
+}
+
+// 初始化
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Stetho.initializeWithDefaults(this);
+ }
+}
+
+// 添加到 OkHttpClient
+OkHttpClient client = new OkHttpClient.Builder()
+ .addNetworkInterceptor(new StethoInterceptor())
+ .build();
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 如何优化网络请求?
+
+**答案:**
+1. **请求合并**:将多个请求合并为一个批量请求
+2. **请求去重**:避免重复请求相同数据
+3. **请求优先级**:重要请求优先处理
+4. **请求重试**:失败请求自动重试
+5. **连接池优化**:复用连接,减少建立连接时间
+6. **超时设置**:合理设置超时时间
+
+### Q2: 如何优化图片加载?
+
+**答案:**
+1. 使用图片加载库(Glide、Picasso)
+2. 图片压缩:使用合适的尺寸和格式
+3. 使用 WebP 格式
+4. 懒加载:只在可见时加载
+5. 预加载:提前加载可能需要的图片
+6. 三级缓存:内存缓存 + 磁盘缓存 + 网络
+
+### Q3: 什么是三级缓存?
+
+**答案:**
+1. **内存缓存**:最快,但容量有限
+2. **磁盘缓存**:速度中等,容量较大
+3. **网络加载**:最慢,但数据最新
+
+### Q4: 如何实现数据压缩?
+
+**答案:**
+1. **Gzip 压缩**:HTTP 请求响应压缩
+2. **数据格式优化**:使用 Protobuf、MessagePack 替代 JSON
+3. **分页加载**:减少单次请求数据量
+4. **字段精简**:只请求必要字段
+
+### Q5: 缓存策略有哪些?
+
+**答案:**
+1. **HTTP 缓存**:利用 HTTP 缓存头(Cache-Control、ETag)
+2. **内存缓存**:使用 LruCache
+3. **磁盘缓存**:持久化缓存
+4. **智能缓存**:根据数据更新频率选择缓存策略
+
+### Q6: 如何监控网络性能?
+
+**答案:**
+1. 使用 Network Profiler 实时监控
+2. 使用拦截器记录请求信息
+3. 监听网络状态变化
+4. 检测网络质量
+5. 使用 Chrome DevTools、Charles 等工具
+
+### Q7: 网络优化的最佳实践?
+
+**答案:**
+1. 合并请求,减少请求次数
+2. 使用缓存,减少网络请求
+3. 压缩数据,减少传输量
+4. 优化图片,使用合适格式和尺寸
+5. 监控网络,及时发现问题
+6. 处理网络异常,提供降级方案
+
+---
+
+## 总结
+
+网络优化是 Android 性能优化的重要部分,主要从以下几个方面入手:
+
+1. **请求优化**:合并、去重、优先级、重试
+2. **图片优化**:压缩、格式、懒加载、缓存
+3. **数据压缩**:Gzip、格式优化、分页
+4. **缓存策略**:三级缓存、智能缓存
+5. **网络监控**:状态监听、请求监控、质量检测
+
+通过合理的网络优化,可以减少网络请求,提升加载速度,改善用户体验。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/数据存储/MMKV.md b/docs/android面试/数据存储/MMKV.md
new file mode 100644
index 0000000..f440fd9
--- /dev/null
+++ b/docs/android面试/数据存储/MMKV.md
@@ -0,0 +1,218 @@
+# MMKV
+
+## 目录
+- [MMKV原理](#mmkv原理)
+- [MMKV优势](#mmkv优势)
+- [MMKV使用](#mmkv使用)
+- [MMKV性能](#mmkv性能)
+- [MMKV与SharedPreferences对比](#mmkv与sharedpreferences对比)
+- [MMKV最佳实践](#mmkv最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## MMKV原理
+
+### MMKV 简介
+
+```java
+// MMKV:高性能键值存储框架
+// - 基于 mmap 内存映射
+// - 高性能、低延迟
+// - 支持多进程
+```
+
+### 存储原理
+
+```java
+// MMKV 使用 mmap 内存映射
+// 1. 将文件映射到内存
+// 2. 直接操作内存,自动同步到文件
+// 3. 避免系统调用,性能更好
+```
+
+---
+
+## MMKV优势
+
+### 性能优势
+
+```java
+// MMKV 性能优势:
+// 1. 基于 mmap,性能更好
+// 2. 支持多进程,无需序列化
+// 3. 增量更新,只写入变更部分
+// 4. 无拷贝操作,直接操作内存
+```
+
+### 功能优势
+
+```java
+// MMKV 功能优势:
+// 1. 支持多进程
+// 2. 支持加密
+// 3. 支持自定义序列化
+// 4. API 简洁
+```
+
+---
+
+## MMKV使用
+
+### 基本使用
+
+```java
+// 初始化
+MMKV.initialize(context);
+
+// 获取默认实例
+MMKV kv = MMKV.defaultMMKV();
+
+// 写入数据
+kv.encode("string", "value");
+kv.encode("int", 123);
+kv.encode("bool", true);
+kv.encode("float", 1.23f);
+
+// 读取数据
+String str = kv.decodeString("string", "default");
+int i = kv.decodeInt("int", 0);
+boolean b = kv.decodeBool("bool", false);
+float f = kv.decodeFloat("float", 0.0f);
+
+// 删除数据
+kv.removeValueForKey("string");
+kv.clearAll();
+```
+
+### 多实例
+
+```java
+// 创建多实例
+MMKV kv1 = MMKV.mmkvWithID("id1");
+MMKV kv2 = MMKV.mmkvWithID("id2");
+
+// 多进程实例
+MMKV kv = MMKV.mmkvWithID("multi_process", MMKV.MULTI_PROCESS_MODE);
+```
+
+### 加密
+
+```java
+// 加密实例
+String cryptKey = "MyEncryptionKey";
+MMKV kv = MMKV.mmkvWithID("encrypted", MMKV.SINGLE_PROCESS_MODE, cryptKey);
+```
+
+---
+
+## MMKV性能
+
+### 性能对比
+
+```java
+// MMKV vs SharedPreferences
+// 写入性能:MMKV 快 100-300 倍
+// 读取性能:MMKV 快 10-50 倍
+// 多进程:MMKV 支持,SharedPreferences 不支持
+```
+
+### 性能测试
+
+```java
+// 写入测试
+long start = System.currentTimeMillis();
+for (int i = 0; i < 10000; i++) {
+ mmkv.encode("key" + i, "value" + i);
+}
+long end = System.currentTimeMillis();
+Log.d("MMKV", "Write time: " + (end - start) + "ms");
+```
+
+---
+
+## MMKV与SharedPreferences对比
+
+### 对比表
+
+| 特性 | MMKV | SharedPreferences |
+|------|------|-------------------|
+| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
+| 多进程 | ✅ | ❌ |
+| 加密 | ✅ | ❌ |
+| 增量更新 | ✅ | ❌ |
+| 易用性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
+
+### 迁移方案
+
+```java
+// 从 SharedPreferences 迁移到 MMKV
+SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
+MMKV mmkv = MMKV.defaultMMKV();
+
+Map all = prefs.getAll();
+for (Map.Entry entry : all.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (value instanceof String) {
+ mmkv.encode(key, (String) value);
+ } else if (value instanceof Integer) {
+ mmkv.encode(key, (Integer) value);
+ }
+ // ... 其他类型
+}
+```
+
+---
+
+## MMKV最佳实践
+
+### 1. 使用单例
+
+```java
+// 使用默认实例或单例
+MMKV kv = MMKV.defaultMMKV();
+```
+
+### 2. 批量操作
+
+```java
+// MMKV 支持批量操作
+// 但通常不需要,因为性能已经很好
+```
+
+### 3. 多进程使用
+
+```java
+// 多进程场景使用 MULTI_PROCESS_MODE
+MMKV kv = MMKV.mmkvWithID("multi", MMKV.MULTI_PROCESS_MODE);
+```
+
+---
+
+## 面试常见问题
+
+### Q1: MMKV 的原理?
+
+**答案:**
+- 基于 mmap 内存映射
+- 将文件映射到内存,直接操作内存
+- 自动同步到文件,性能更好
+
+### Q2: MMKV 的优势?
+
+**答案:**
+1. 性能好:比 SharedPreferences 快很多
+2. 支持多进程
+3. 支持加密
+4. 增量更新
+
+### Q3: MMKV 和 SharedPreferences 的区别?
+
+**答案:**
+- **MMKV**:性能好,支持多进程,支持加密
+- **SharedPreferences**:性能一般,不支持多进程,不支持加密
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/数据存储/Room数据库.md b/docs/android面试/数据存储/Room数据库.md
new file mode 100644
index 0000000..3ef722a
--- /dev/null
+++ b/docs/android面试/数据存储/Room数据库.md
@@ -0,0 +1,358 @@
+# Room数据库
+
+## 目录
+- [Room架构](#room架构)
+- [Entity定义](#entity定义)
+- [DAO接口](#dao接口)
+- [Database配置](#database配置)
+- [Room迁移](#room迁移)
+- [Room与LiveData](#room与livedata)
+- [Room最佳实践](#room最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Room架构
+
+### Room 组件
+
+```
+┌─────────────┐
+│ Entity │ ←─── 数据模型
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ DAO │ ←─── 数据访问接口
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Database │ ←─── 数据库配置
+└─────────────┘
+```
+
+### Room 优势
+
+1. **编译时检查**:SQL 语句编译时检查
+2. **类型安全**:类型安全的数据访问
+3. **支持 LiveData**:自动更新 UI
+4. **支持 RxJava**:响应式编程
+5. **简化代码**:减少样板代码
+
+---
+
+## Entity定义
+
+### Entity 注解
+
+```java
+// Entity:数据模型
+@Entity(tableName = "user")
+public class User {
+ @PrimaryKey(autoGenerate = true)
+ private int id;
+
+ @ColumnInfo(name = "user_name")
+ private String name;
+
+ private String email;
+
+ private int age;
+
+ // Getters and Setters
+ public int getId() { return id; }
+ public void setId(int id) { this.id = id; }
+
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+
+ public String getEmail() { return email; }
+ public void setEmail(String email) { this.email = email; }
+
+ public int getAge() { return age; }
+ public void setAge(int age) { this.age = age; }
+}
+```
+
+### Entity 注解选项
+
+```java
+@Entity(
+ tableName = "user",
+ indices = {@Index("name"), @Index(value = {"name", "age"})},
+ foreignKeys = {
+ @ForeignKey(
+ entity = Department.class,
+ parentColumns = "id",
+ childColumns = "department_id"
+ )
+ }
+)
+public class User {
+ @PrimaryKey
+ private int id;
+
+ @ColumnInfo(name = "department_id")
+ private int departmentId;
+}
+```
+
+---
+
+## DAO接口
+
+### DAO 定义
+
+```java
+// DAO:数据访问对象
+@Dao
+public interface UserDao {
+ // 查询
+ @Query("SELECT * FROM user")
+ List getAllUsers();
+
+ @Query("SELECT * FROM user WHERE id = :id")
+ User getUserById(int id);
+
+ @Query("SELECT * FROM user WHERE age > :age")
+ List getUsersByAge(int age);
+
+ // 插入
+ @Insert
+ void insertUser(User user);
+
+ @Insert
+ void insertUsers(User... users);
+
+ // 更新
+ @Update
+ void updateUser(User user);
+
+ // 删除
+ @Delete
+ void deleteUser(User user);
+
+ @Query("DELETE FROM user WHERE id = :id")
+ void deleteUserById(int id);
+}
+```
+
+### 复杂查询
+
+```java
+@Dao
+public interface UserDao {
+ // 多表查询
+ @Query("SELECT * FROM user u INNER JOIN department d ON u.department_id = d.id")
+ List getUsersWithDepartment();
+
+ // 参数查询
+ @Query("SELECT * FROM user WHERE name LIKE :name AND age > :age")
+ List searchUsers(String name, int age);
+
+ // 返回 LiveData
+ @Query("SELECT * FROM user")
+ LiveData
> getAllUsersLive();
+
+ // 返回 Flowable(RxJava)
+ @Query("SELECT * FROM user")
+ Flowable> getAllUsersFlowable();
+}
+```
+
+---
+
+## Database配置
+
+### Database 定义
+
+```java
+// Database:数据库配置
+@Database(
+ entities = {User.class, Department.class},
+ version = 1,
+ exportSchema = false
+)
+public abstract class AppDatabase extends RoomDatabase {
+ public abstract UserDao userDao();
+ public abstract DepartmentDao departmentDao();
+
+ private static AppDatabase instance;
+
+ public static synchronized AppDatabase getInstance(Context context) {
+ if (instance == null) {
+ instance = Room.databaseBuilder(
+ context.getApplicationContext(),
+ AppDatabase.class,
+ "app_database"
+ ).build();
+ }
+ return instance;
+ }
+}
+```
+
+### Database 配置选项
+
+```java
+Room.databaseBuilder(context, AppDatabase.class, "database_name")
+ .allowMainThreadQueries() // 允许主线程查询(不推荐)
+ .fallbackToDestructiveMigration() // 破坏性迁移
+ .addMigrations(MIGRATION_1_2, MIGRATION_2_3) // 迁移
+ .build();
+```
+
+---
+
+## Room迁移
+
+### 数据库迁移
+
+```java
+// 版本1 → 版本2
+static final Migration MIGRATION_1_2 = new Migration(1, 2) {
+ @Override
+ public void migrate(SupportSQLiteDatabase database) {
+ database.execSQL("ALTER TABLE user ADD COLUMN phone TEXT");
+ }
+};
+
+// 版本2 → 版本3
+static final Migration MIGRATION_2_3 = new Migration(2, 3) {
+ @Override
+ public void migrate(SupportSQLiteDatabase database) {
+ database.execSQL("CREATE TABLE address (" +
+ "id INTEGER PRIMARY KEY AUTOINCREMENT," +
+ "user_id INTEGER," +
+ "address TEXT" +
+ ")");
+ }
+};
+
+// 配置迁移
+Room.databaseBuilder(context, AppDatabase.class, "database_name")
+ .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
+ .build();
+```
+
+---
+
+## Room与LiveData
+
+### LiveData 集成
+
+```java
+// DAO 返回 LiveData
+@Dao
+public interface UserDao {
+ @Query("SELECT * FROM user")
+ LiveData> getAllUsers();
+
+ @Query("SELECT * FROM user WHERE id = :id")
+ LiveData getUserById(int id);
+}
+
+// 观察数据变化
+userDao.getAllUsers().observe(this, users -> {
+ adapter.updateUsers(users);
+});
+```
+
+### RxJava 集成
+
+```java
+// 添加依赖
+dependencies {
+ implementation 'androidx.room:room-rxjava2:2.3.0'
+}
+
+// DAO 返回 Flowable
+@Dao
+public interface UserDao {
+ @Query("SELECT * FROM user")
+ Flowable> getAllUsers();
+}
+
+// 使用
+userDao.getAllUsers()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(users -> {
+ adapter.updateUsers(users);
+ });
+```
+
+---
+
+## Room最佳实践
+
+### 1. 使用单例模式
+
+```java
+// 数据库使用单例
+public static synchronized AppDatabase getInstance(Context context) {
+ if (instance == null) {
+ instance = Room.databaseBuilder(...).build();
+ }
+ return instance;
+}
+```
+
+### 2. 在后台线程操作
+
+```java
+// ✅ 正确:在后台线程操作
+new Thread(() -> {
+ userDao.insertUser(user);
+}).start();
+
+// ❌ 错误:在主线程操作(除非使用 allowMainThreadQueries)
+userDao.insertUser(user);
+```
+
+### 3. 使用事务
+
+```java
+@Dao
+public interface UserDao {
+ @Transaction
+ @Query("SELECT * FROM user")
+ List getAllUsers();
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Room 的优势?
+
+**答案:**
+1. 编译时检查 SQL
+2. 类型安全
+3. 支持 LiveData
+4. 支持 RxJava
+5. 简化代码
+
+### Q2: Room 的组件?
+
+**答案:**
+1. **Entity**:数据模型
+2. **DAO**:数据访问接口
+3. **Database**:数据库配置
+
+### Q3: Room 迁移?
+
+**答案:**
+- 使用 Migration 类处理数据库升级
+- 定义迁移规则
+- 在 Database 配置中添加迁移
+
+### Q4: Room 和 SQLite 的区别?
+
+**答案:**
+- **Room**:SQLite 的封装,提供类型安全、编译时检查
+- **SQLite**:底层数据库,需要手动编写 SQL
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/数据存储/SQLite数据库.md b/docs/android面试/数据存储/SQLite数据库.md
new file mode 100644
index 0000000..0e1171f
--- /dev/null
+++ b/docs/android面试/数据存储/SQLite数据库.md
@@ -0,0 +1,327 @@
+# SQLite数据库
+
+## 目录
+- [SQLite基础](#sqlite基础)
+- [SQLite操作](#sqlite操作)
+- [SQLite性能优化](#sqlite性能优化)
+- [SQLite事务](#sqlite事务)
+- [SQLite索引](#sqlite索引)
+- [SQLite最佳实践](#sqlite最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## SQLite基础
+
+### SQLite 简介
+
+```java
+// SQLite:轻量级关系型数据库
+// - 嵌入式数据库
+// - 无需服务器
+// - 支持 SQL 语法
+// - 适合移动应用
+```
+
+### 创建数据库
+
+```java
+public class DatabaseHelper extends SQLiteOpenHelper {
+ private static final String DATABASE_NAME = "my_database.db";
+ private static final int DATABASE_VERSION = 1;
+
+ public DatabaseHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // 创建表
+ db.execSQL("CREATE TABLE user (" +
+ "id INTEGER PRIMARY KEY AUTOINCREMENT," +
+ "name TEXT NOT NULL," +
+ "email TEXT," +
+ "age INTEGER" +
+ ")");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 升级数据库
+ db.execSQL("DROP TABLE IF EXISTS user");
+ onCreate(db);
+ }
+}
+```
+
+---
+
+## SQLite操作
+
+### 插入数据
+
+```java
+// 方式1:使用 execSQL
+db.execSQL("INSERT INTO user (name, email, age) VALUES (?, ?, ?)",
+ new String[]{"John", "john@example.com", "25"});
+
+// 方式2:使用 insert
+ContentValues values = new ContentValues();
+values.put("name", "John");
+values.put("email", "john@example.com");
+values.put("age", 25);
+long id = db.insert("user", null, values);
+```
+
+### 查询数据
+
+```java
+// 查询所有
+Cursor cursor = db.query("user", null, null, null, null, null, null);
+
+// 条件查询
+Cursor cursor = db.query("user",
+ new String[]{"id", "name", "email"},
+ "age > ?",
+ new String[]{"18"},
+ null, null, "name ASC");
+
+// 使用 SQL
+Cursor cursor = db.rawQuery("SELECT * FROM user WHERE age > ?", new String[]{"18"});
+
+// 遍历结果
+while (cursor.moveToNext()) {
+ int id = cursor.getInt(cursor.getColumnIndex("id"));
+ String name = cursor.getString(cursor.getColumnIndex("name"));
+ String email = cursor.getString(cursor.getColumnIndex("email"));
+}
+cursor.close();
+```
+
+### 更新数据
+
+```java
+// 方式1:使用 execSQL
+db.execSQL("UPDATE user SET name = ? WHERE id = ?",
+ new String[]{"Jane", "1"});
+
+// 方式2:使用 update
+ContentValues values = new ContentValues();
+values.put("name", "Jane");
+int count = db.update("user", values, "id = ?", new String[]{"1"});
+```
+
+### 删除数据
+
+```java
+// 方式1:使用 execSQL
+db.execSQL("DELETE FROM user WHERE id = ?", new String[]{"1"});
+
+// 方式2:使用 delete
+int count = db.delete("user", "id = ?", new String[]{"1"});
+```
+
+---
+
+## SQLite性能优化
+
+### 1. 使用索引
+
+```java
+// 创建索引
+db.execSQL("CREATE INDEX idx_name ON user(name)");
+```
+
+### 2. 使用事务
+
+```java
+// 批量操作使用事务
+db.beginTransaction();
+try {
+ for (int i = 0; i < 1000; i++) {
+ db.insert("user", null, values);
+ }
+ db.setTransactionSuccessful();
+} finally {
+ db.endTransaction();
+}
+```
+
+### 3. 使用预编译语句
+
+```java
+// 使用 SQLiteStatement
+SQLiteStatement stmt = db.compileStatement(
+ "INSERT INTO user (name, email) VALUES (?, ?)");
+stmt.bindString(1, "John");
+stmt.bindString(2, "john@example.com");
+stmt.executeInsert();
+stmt.close();
+```
+
+### 4. 避免 N+1 查询
+
+```java
+// ❌ 问题:N+1 查询
+List users = getUsers();
+for (User user : users) {
+ List orders = getOrdersByUserId(user.getId()); // N 次查询
+}
+
+// ✅ 解决:使用 JOIN
+SELECT u.*, o.* FROM user u LEFT JOIN order o ON u.id = o.user_id
+```
+
+---
+
+## SQLite事务
+
+### 事务使用
+
+```java
+// 开始事务
+db.beginTransaction();
+try {
+ // 执行多个操作
+ db.insert("user", null, values1);
+ db.insert("user", null, values2);
+ db.insert("user", null, values3);
+
+ // 标记事务成功
+ db.setTransactionSuccessful();
+} finally {
+ // 结束事务(如果未标记成功,会回滚)
+ db.endTransaction();
+}
+```
+
+### 事务优势
+
+```java
+// 1. 原子性:要么全部成功,要么全部失败
+// 2. 性能:批量操作性能更好
+// 3. 一致性:保证数据一致性
+```
+
+---
+
+## SQLite索引
+
+### 创建索引
+
+```java
+// 单列索引
+db.execSQL("CREATE INDEX idx_name ON user(name)");
+
+// 复合索引
+db.execSQL("CREATE INDEX idx_name_age ON user(name, age)");
+
+// 唯一索引
+db.execSQL("CREATE UNIQUE INDEX idx_email ON user(email)");
+```
+
+### 索引使用
+
+```java
+// 索引会加速查询
+// 但会增加写入开销和存储空间
+
+// 适合创建索引的列:
+// 1. 经常用于 WHERE 条件的列
+// 2. 经常用于 JOIN 的列
+// 3. 经常用于 ORDER BY 的列
+```
+
+---
+
+## SQLite最佳实践
+
+### 1. 使用事务
+
+```java
+// 批量操作使用事务
+db.beginTransaction();
+try {
+ // 批量操作
+ db.setTransactionSuccessful();
+} finally {
+ db.endTransaction();
+}
+```
+
+### 2. 及时关闭 Cursor
+
+```java
+// ✅ 正确
+Cursor cursor = db.query(...);
+try {
+ // 使用 cursor
+} finally {
+ cursor.close();
+}
+
+// ❌ 错误:忘记关闭
+Cursor cursor = db.query(...);
+// 使用 cursor
+// 忘记关闭,可能导致内存泄漏
+```
+
+### 3. 使用预编译语句
+
+```java
+// 重复执行的 SQL 使用预编译语句
+SQLiteStatement stmt = db.compileStatement("INSERT INTO user (name) VALUES (?)");
+```
+
+### 4. 数据库升级
+
+```java
+@Override
+public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // 根据版本号升级
+ if (oldVersion < 2) {
+ // 升级到版本2
+ }
+ if (oldVersion < 3) {
+ // 升级到版本3
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: SQLite 的特点?
+
+**答案:**
+- 轻量级关系型数据库
+- 嵌入式数据库,无需服务器
+- 支持 SQL 语法
+- 适合移动应用
+
+### Q2: 如何优化 SQLite 性能?
+
+**答案:**
+1. 使用索引
+2. 使用事务
+3. 使用预编译语句
+4. 避免 N+1 查询
+
+### Q3: SQLite 事务的作用?
+
+**答案:**
+1. 原子性:保证操作要么全部成功,要么全部失败
+2. 性能:批量操作性能更好
+3. 一致性:保证数据一致性
+
+### Q4: 什么时候创建索引?
+
+**答案:**
+- 经常用于 WHERE 条件的列
+- 经常用于 JOIN 的列
+- 经常用于 ORDER BY 的列
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/数据存储/SharedPreferences.md b/docs/android面试/数据存储/SharedPreferences.md
new file mode 100644
index 0000000..c6bbd61
--- /dev/null
+++ b/docs/android面试/数据存储/SharedPreferences.md
@@ -0,0 +1,278 @@
+# SharedPreferences
+
+## 目录
+- [SharedPreferences原理](#sharedpreferences原理)
+- [SharedPreferences使用](#sharedpreferences使用)
+- [SharedPreferences性能](#sharedpreferences性能)
+- [SharedPreferences线程安全](#sharedpreferences线程安全)
+- [SharedPreferences替代方案](#sharedpreferences替代方案)
+- [SharedPreferences最佳实践](#sharedpreferences最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## SharedPreferences原理
+
+### 存储位置
+
+```java
+// SharedPreferences 存储在 XML 文件中
+// 路径:/data/data//shared_prefs/.xml
+
+// 文件内容示例
+
+
+```
+
+### 存储机制
+
+```java
+// SharedPreferences 使用内存缓存 + 文件存储
+// 1. 首次读取:从文件加载到内存
+// 2. 后续读取:从内存读取(快速)
+// 3. 写入:先写入内存,异步写入文件
+```
+
+---
+
+## SharedPreferences使用
+
+### 基本使用
+
+```java
+// 获取 SharedPreferences
+SharedPreferences prefs = getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
+
+// 写入数据
+SharedPreferences.Editor editor = prefs.edit();
+editor.putString("username", "John");
+editor.putInt("age", 25);
+editor.putBoolean("isVip", true);
+editor.apply(); // 异步提交
+// 或
+editor.commit(); // 同步提交
+
+// 读取数据
+String username = prefs.getString("username", "default");
+int age = prefs.getInt("age", 0);
+boolean isVip = prefs.getBoolean("isVip", false);
+```
+
+### apply vs commit
+
+```java
+// apply():异步提交
+editor.apply();
+// 优点:不阻塞主线程
+// 缺点:无法知道是否成功
+
+// commit():同步提交
+boolean success = editor.commit();
+// 优点:可以知道是否成功
+// 缺点:可能阻塞主线程
+```
+
+### 监听数据变化
+
+```java
+// 注册监听器
+SharedPreferences.OnSharedPreferenceChangeListener listener =
+ new SharedPreferences.OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if ("username".equals(key)) {
+ String username = sharedPreferences.getString(key, "");
+ // 处理变化
+ }
+ }
+ };
+
+prefs.registerOnSharedPreferenceChangeListener(listener);
+
+// 注销监听器
+prefs.unregisterOnSharedPreferenceChangeListener(listener);
+```
+
+---
+
+## SharedPreferences性能
+
+### 性能问题
+
+```java
+// ❌ 问题:频繁读写
+for (int i = 0; i < 1000; i++) {
+ SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
+ prefs.edit().putString("key" + i, "value" + i).apply();
+}
+
+// ✅ 解决:批量写入
+SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
+SharedPreferences.Editor editor = prefs.edit();
+for (int i = 0; i < 1000; i++) {
+ editor.putString("key" + i, "value" + i);
+}
+editor.apply(); // 一次性提交
+```
+
+### 性能优化
+
+```java
+// 1. 使用 apply() 而不是 commit()
+editor.apply();
+
+// 2. 批量写入
+editor.putString("key1", "value1");
+editor.putString("key2", "value2");
+editor.apply();
+
+// 3. 避免频繁读取
+// 缓存到内存变量
+```
+
+---
+
+## SharedPreferences线程安全
+
+### 线程安全说明
+
+```java
+// SharedPreferences 是线程安全的
+// 多个线程可以同时读取
+// 写入操作会加锁
+
+// 读取:线程安全
+String value = prefs.getString("key", "default");
+
+// 写入:线程安全
+prefs.edit().putString("key", "value").apply();
+```
+
+### 并发写入
+
+```java
+// 多个线程同时写入
+// SharedPreferences 内部会加锁,保证线程安全
+// 但可能导致性能问题
+
+// 建议:避免多线程频繁写入
+```
+
+---
+
+## SharedPreferences替代方案
+
+### 1. MMKV
+
+```java
+// MMKV:高性能键值存储
+MMKV mmkv = MMKV.defaultMMKV();
+mmkv.encode("username", "John");
+String username = mmkv.decodeString("username");
+```
+
+### 2. DataStore
+
+```kotlin
+// DataStore:Jetpack 组件
+val dataStore: DataStore = context.createDataStore(name = "settings")
+
+// 写入
+suspend fun saveUsername(username: String) {
+ dataStore.edit { preferences ->
+ preferences[stringPreferencesKey("username")] = username
+ }
+}
+
+// 读取
+val usernameFlow: Flow = dataStore.data
+ .map { preferences ->
+ preferences[stringPreferencesKey("username")] ?: ""
+ }
+```
+
+### 3. Room
+
+```java
+// Room:适合复杂数据
+@Database(entities = {User.class}, version = 1)
+public abstract class AppDatabase extends RoomDatabase {
+ public abstract UserDao userDao();
+}
+```
+
+---
+
+## SharedPreferences最佳实践
+
+### 1. 使用 apply()
+
+```java
+// ✅ 推荐:使用 apply()
+editor.apply();
+
+// ❌ 不推荐:使用 commit()(除非需要知道结果)
+editor.commit();
+```
+
+### 2. 批量写入
+
+```java
+// ✅ 批量写入
+editor.putString("key1", "value1");
+editor.putString("key2", "value2");
+editor.apply();
+
+// ❌ 多次写入
+editor.putString("key1", "value1").apply();
+editor.putString("key2", "value2").apply();
+```
+
+### 3. 避免存储大量数据
+
+```java
+// ❌ 不推荐:存储大量数据
+editor.putString("largeData", largeString);
+
+// ✅ 推荐:使用文件存储
+saveToFile(largeData);
+```
+
+---
+
+## 面试常见问题
+
+### Q1: SharedPreferences 的原理?
+
+**答案:**
+- 存储在 XML 文件中
+- 使用内存缓存 + 文件存储
+- 首次读取从文件加载,后续从内存读取
+
+### Q2: apply() 和 commit() 的区别?
+
+**答案:**
+- **apply()**:异步提交,不阻塞主线程
+- **commit()**:同步提交,返回结果,可能阻塞主线程
+
+### Q3: SharedPreferences 是否线程安全?
+
+**答案:**
+- 是线程安全的
+- 多个线程可以同时读取
+- 写入操作会加锁
+
+### Q4: SharedPreferences 的替代方案?
+
+**答案:**
+1. **MMKV**:高性能键值存储
+2. **DataStore**:Jetpack 组件
+3. **Room**:适合复杂数据
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/数据存储/文件存储.md b/docs/android面试/数据存储/文件存储.md
new file mode 100644
index 0000000..e4695c5
--- /dev/null
+++ b/docs/android面试/数据存储/文件存储.md
@@ -0,0 +1,334 @@
+# 文件存储
+
+## 目录
+- [内部存储](#内部存储)
+- [外部存储](#外部存储)
+- [文件操作](#文件操作)
+- [文件权限](#文件权限)
+- [文件加密](#文件加密)
+- [文件存储最佳实践](#文件存储最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 内部存储
+
+### 内部存储特点
+
+```java
+// 内部存储:
+// - 应用私有,其他应用无法访问
+// - 卸载应用时自动删除
+// - 不需要权限
+// - 路径:/data/data//files/
+```
+
+### 内部存储使用
+
+```java
+// 写入文件
+String filename = "myfile.txt";
+String content = "Hello World";
+
+try (FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE)) {
+ fos.write(content.getBytes());
+} catch (IOException e) {
+ e.printStackTrace();
+}
+
+// 读取文件
+try (FileInputStream fis = openFileInput(filename)) {
+ byte[] buffer = new byte[1024];
+ int length = fis.read(buffer);
+ String content = new String(buffer, 0, length);
+} catch (IOException e) {
+ e.printStackTrace();
+}
+
+// 删除文件
+deleteFile(filename);
+
+// 列出文件
+String[] files = fileList();
+```
+
+### 存储模式
+
+```java
+// MODE_PRIVATE:私有模式(默认)
+openFileOutput(filename, Context.MODE_PRIVATE);
+
+// MODE_APPEND:追加模式
+openFileOutput(filename, Context.MODE_APPEND);
+
+// MODE_WORLD_READABLE:可读(已废弃)
+// MODE_WORLD_WRITEABLE:可写(已废弃)
+```
+
+---
+
+## 外部存储
+
+### 外部存储特点
+
+```java
+// 外部存储:
+// - 可以被其他应用访问(需要权限)
+// - 卸载应用时不会自动删除
+// - 需要权限(Android 6.0+)
+// - 路径:/sdcard/ 或 /storage/emulated/0/
+```
+
+### 外部存储使用
+
+#### Android 10 之前
+
+```java
+// 检查外部存储是否可用
+if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ // 外部存储可用
+
+ // 获取外部存储目录
+ File externalDir = Environment.getExternalStorageDirectory();
+ File file = new File(externalDir, "myfile.txt");
+
+ // 写入文件
+ try (FileWriter writer = new FileWriter(file)) {
+ writer.write("Hello World");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}
+```
+
+#### Android 10+(分区存储)
+
+```java
+// 使用 MediaStore 访问文件
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ContentValues values = new ContentValues();
+ values.put(MediaStore.Images.Media.DISPLAY_NAME, "image.jpg");
+ values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
+ values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
+
+ Uri uri = getContentResolver().insert(
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+
+ try (OutputStream os = getContentResolver().openOutputStream(uri)) {
+ // 写入文件
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}
+```
+
+### 应用私有外部存储
+
+```java
+// 应用私有外部存储
+// 路径:/sdcard/Android/data//
+// 卸载应用时自动删除
+
+File externalFilesDir = getExternalFilesDir(null);
+File file = new File(externalFilesDir, "myfile.txt");
+```
+
+---
+
+## 文件操作
+
+### 文件读写
+
+```java
+// 写入文件
+public void writeFile(String filename, String content) {
+ try (FileWriter writer = new FileWriter(filename)) {
+ writer.write(content);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}
+
+// 读取文件
+public String readFile(String filename) {
+ StringBuilder content = new StringBuilder();
+ try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ content.append(line).append("\n");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return content.toString();
+}
+```
+
+### 文件复制
+
+```java
+public void copyFile(File source, File dest) {
+ try (InputStream is = new FileInputStream(source);
+ OutputStream os = new FileOutputStream(dest)) {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = is.read(buffer)) > 0) {
+ os.write(buffer, 0, length);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}
+```
+
+### 文件删除
+
+```java
+// 删除文件
+File file = new File(path);
+if (file.exists()) {
+ file.delete();
+}
+
+// 删除目录
+public void deleteDirectory(File directory) {
+ if (directory.exists()) {
+ File[] files = directory.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ if (file.isDirectory()) {
+ deleteDirectory(file);
+ } else {
+ file.delete();
+ }
+ }
+ }
+ directory.delete();
+ }
+}
+```
+
+---
+
+## 文件权限
+
+### 权限申请
+
+```java
+// Android 6.0+ 需要运行时申请
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ REQUEST_CODE);
+ }
+}
+```
+
+### Android 10+ 权限变化
+
+```java
+// Android 10+ 分区存储
+// - 应用私有目录:不需要权限
+// - 共享存储:使用 MediaStore,不需要权限
+// - 其他目录:需要 MANAGE_EXTERNAL_STORAGE 权限
+```
+
+---
+
+## 文件加密
+
+### 文件加密示例
+
+```java
+// 使用 AES 加密
+public void encryptFile(File inputFile, File outputFile, String password) {
+ try {
+ SecretKeySpec key = new SecretKeySpec(
+ password.getBytes(), "AES");
+ Cipher cipher = Cipher.getInstance("AES");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+
+ try (FileInputStream fis = new FileInputStream(inputFile);
+ FileOutputStream fos = new FileOutputStream(outputFile);
+ CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = fis.read(buffer)) > 0) {
+ cos.write(buffer, 0, length);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+}
+```
+
+---
+
+## 文件存储最佳实践
+
+### 1. 选择合适的存储位置
+
+```java
+// 应用私有数据 → 内部存储
+// 用户生成内容 → 外部存储(应用私有目录)
+// 共享文件 → MediaStore
+```
+
+### 2. 及时关闭流
+
+```java
+// ✅ 使用 try-with-resources
+try (FileInputStream fis = new FileInputStream(file)) {
+ // 使用流
+}
+
+// ❌ 忘记关闭流
+FileInputStream fis = new FileInputStream(file);
+// 使用流
+// 忘记关闭,可能导致资源泄漏
+```
+
+### 3. 异步操作
+
+```java
+// 文件操作在后台线程执行
+new Thread(() -> {
+ writeFile(file, content);
+ runOnUiThread(() -> {
+ // 更新 UI
+ });
+}).start();
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 内部存储和外部存储的区别?
+
+**答案:**
+- **内部存储**:应用私有,卸载时删除,不需要权限
+- **外部存储**:可被其他应用访问,卸载时不删除,需要权限
+
+### Q2: Android 10 分区存储?
+
+**答案:**
+- 限制应用访问外部存储
+- 使用 MediaStore 访问媒体文件
+- 使用 SAF 访问其他文件
+- 提升用户隐私保护
+
+### Q3: 文件存储的权限?
+
+**答案:**
+- **内部存储**:不需要权限
+- **外部存储**:Android 6.0+ 需要运行时申请
+- **Android 10+**:应用私有目录不需要权限
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/核心组件/Activity详解.md b/docs/android面试/核心组件/Activity详解.md
new file mode 100644
index 0000000..a3f9409
--- /dev/null
+++ b/docs/android面试/核心组件/Activity详解.md
@@ -0,0 +1,592 @@
+# Activity详解
+
+## 目录
+- [Activity生命周期](#activity生命周期)
+- [Activity启动模式](#activity启动模式)
+- [Activity任务栈](#activity任务栈)
+- [Activity与Fragment通信](#activity与fragment通信)
+- [Activity重建](#activity重建)
+- [Activity转场动画](#activity转场动画)
+- [Activity最佳实践](#activity最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Activity生命周期
+
+### 生命周期方法
+
+```java
+public class MainActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Activity 创建时调用
+ // 初始化视图、数据绑定
+ setContentView(R.layout.activity_main);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ // Activity 可见但不可交互
+ // 注册广播、启动动画
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ // Activity 可见且可交互
+ // 恢复动画、开始数据更新
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ // Activity 失去焦点
+ // 暂停动画、保存数据
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ // Activity 不可见
+ // 停止动画、注销广播
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ // Activity 被销毁
+ // 释放资源、取消网络请求
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onRestart();
+ // Activity 从 onStop 恢复
+ // 重新初始化
+ }
+}
+```
+
+### 生命周期流程图
+
+```
+启动 Activity:
+onCreate() → onStart() → onResume()
+
+按 Home 键:
+onPause() → onStop()
+
+返回 Activity:
+onRestart() → onStart() → onResume()
+
+按 Back 键:
+onPause() → onStop() → onDestroy()
+
+屏幕旋转:
+onPause() → onStop() → onDestroy()
+→ onCreate() → onStart() → onResume()
+```
+
+### 生命周期场景
+
+#### 1. 正常启动和销毁
+
+```java
+// 启动
+onCreate() → onStart() → onResume()
+
+// 销毁
+onPause() → onStop() → onDestroy()
+```
+
+#### 2. 切换到后台
+
+```java
+// 按 Home 键
+onPause() → onStop()
+
+// 返回
+onRestart() → onStart() → onResume()
+```
+
+#### 3. 屏幕旋转
+
+```java
+// 旋转前
+onPause() → onStop() → onDestroy()
+
+// 旋转后
+onCreate() → onStart() → onResume()
+```
+
+---
+
+## Activity启动模式
+
+### 四种启动模式
+
+#### 1. standard(标准模式)
+
+```xml
+
+
+```
+
+**特点:**
+- 每次启动都创建新实例
+- 可以多个实例存在
+- 默认启动模式
+
+```java
+// 示例
+// 启动 MainActivity 3 次,会创建 3 个实例
+Intent intent = new Intent(this, MainActivity.class);
+startActivity(intent); // 实例1
+startActivity(intent); // 实例2
+startActivity(intent); // 实例3
+```
+
+#### 2. singleTop(栈顶复用)
+
+```xml
+
+```
+
+**特点:**
+- 如果 Activity 在栈顶,复用该实例
+- 如果不在栈顶,创建新实例
+- 适合防止重复启动
+
+```java
+// 示例
+// 栈:A → B → C(C 在栈顶)
+// 启动 C:复用 C 实例
+// 启动 B:创建新的 B 实例
+```
+
+#### 3. singleTask(栈内复用)
+
+```xml
+
+```
+
+**特点:**
+- 如果 Activity 在栈中,复用该实例,并清除其上所有 Activity
+- 如果不在栈中,创建新实例
+- 适合主界面
+
+```java
+// 示例
+// 栈:A → B → C
+// 启动 B:复用 B,清除 C,栈变为 A → B
+```
+
+#### 4. singleInstance(单例模式)
+
+```xml
+
+```
+
+**特点:**
+- 单独一个任务栈
+- 全局唯一实例
+- 适合独立功能(如拨号界面)
+
+```java
+// 示例
+// 栈1:A → B
+// 栈2:C(singleInstance)
+// 启动 C:复用栈2中的 C
+```
+
+### Intent Flag
+
+```java
+// 使用 Intent Flag 控制启动模式
+Intent intent = new Intent(this, MainActivity.class);
+
+// FLAG_ACTIVITY_NEW_TASK:在新任务栈中启动
+intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+// FLAG_ACTIVITY_SINGLE_TOP:等同于 singleTop
+intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+
+// FLAG_ACTIVITY_CLEAR_TOP:清除栈顶 Activity
+intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+// FLAG_ACTIVITY_CLEAR_TASK:清除整个任务栈
+intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+startActivity(intent);
+```
+
+---
+
+## Activity任务栈
+
+### 任务栈概念
+
+```java
+// 任务栈(Task Stack)
+// 后进先出(LIFO)的栈结构
+
+// 示例栈结构
+// 栈底 ← → 栈顶
+// A → B → C → D
+
+// 按 Back 键
+// D 出栈 → C 出栈 → B 出栈 → A 出栈
+```
+
+### 任务栈管理
+
+```java
+// 查看任务栈信息
+ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+List tasks = activityManager.getRunningTasks(10);
+
+for (ActivityManager.RunningTaskInfo task : tasks) {
+ Log.d("Task", "Task ID: " + task.id);
+ Log.d("Task", "Top Activity: " + task.topActivity.getClassName());
+}
+```
+
+### 任务栈场景
+
+#### 1. 标准任务栈
+
+```java
+// 启动顺序:A → B → C
+// 栈结构:A → B → C
+// 按 Back:C → B → A
+```
+
+#### 2. singleTask 任务栈
+
+```java
+// 启动顺序:A → B → C → B
+// 栈结构:A → B(C 被清除)
+// 按 Back:B → A
+```
+
+#### 3. singleInstance 任务栈
+
+```java
+// 栈1:A → B
+// 栈2:C(singleInstance)
+// 两个独立的任务栈
+```
+
+---
+
+## Activity与Fragment通信
+
+### 方式1:接口回调
+
+```java
+// Fragment 定义接口
+public class MyFragment extends Fragment {
+ public interface OnFragmentInteractionListener {
+ void onFragmentAction(String data);
+ }
+
+ private OnFragmentInteractionListener listener;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ if (context instanceof OnFragmentInteractionListener) {
+ listener = (OnFragmentInteractionListener) context;
+ }
+ }
+
+ private void sendDataToActivity() {
+ if (listener != null) {
+ listener.onFragmentAction("Data from Fragment");
+ }
+ }
+}
+
+// Activity 实现接口
+public class MainActivity extends AppCompatActivity
+ implements MyFragment.OnFragmentInteractionListener {
+
+ @Override
+ public void onFragmentAction(String data) {
+ // 处理 Fragment 传递的数据
+ Log.d("Activity", "Received: " + data);
+ }
+}
+```
+
+### 方式2:ViewModel 共享
+
+```java
+// ViewModel
+public class SharedViewModel extends ViewModel {
+ private MutableLiveData data = new MutableLiveData<>();
+
+ public LiveData getData() {
+ return data;
+ }
+
+ public void setData(String value) {
+ data.setValue(value);
+ }
+}
+
+// Activity
+public class MainActivity extends AppCompatActivity {
+ private SharedViewModel viewModel;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ viewModel = ViewModelProviders.of(this).get(SharedViewModel.class);
+ }
+}
+
+// Fragment
+public class MyFragment extends Fragment {
+ private SharedViewModel viewModel;
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
+ viewModel.getData().observe(this, data -> {
+ // 观察数据变化
+ });
+ }
+}
+```
+
+### 方式3:EventBus
+
+```java
+// Fragment 发送事件
+EventBus.getDefault().post(new MessageEvent("Data from Fragment"));
+
+// Activity 接收事件
+@Subscribe(threadMode = ThreadMode.MAIN)
+public void onMessageEvent(MessageEvent event) {
+ // 处理事件
+}
+```
+
+---
+
+## Activity重建
+
+### 配置变更
+
+```java
+// 屏幕旋转等配置变更会导致 Activity 重建
+// 默认行为:销毁并重建 Activity
+
+// 保存状态
+@Override
+protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString("key", value);
+}
+
+// 恢复状态
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState != null) {
+ String value = savedInstanceState.getString("key");
+ }
+}
+```
+
+### 避免重建
+
+```xml
+
+
+```
+
+```java
+// 手动处理配置变更
+@Override
+public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // 手动处理配置变更
+ if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ // 横屏处理
+ } else {
+ // 竖屏处理
+ }
+}
+```
+
+### ViewModel 保持数据
+
+```java
+// ViewModel 在配置变更时不会重建
+public class MyViewModel extends ViewModel {
+ private MutableLiveData data = new MutableLiveData<>();
+
+ public LiveData getData() {
+ return data;
+ }
+}
+
+// Activity
+public class MainActivity extends AppCompatActivity {
+ private MyViewModel viewModel;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // ViewModel 在配置变更时保持
+ viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
+ }
+}
+```
+
+---
+
+## Activity转场动画
+
+### 系统动画
+
+```java
+// 启动 Activity
+startActivity(intent);
+overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
+
+// 关闭 Activity
+finish();
+overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
+```
+
+### 共享元素动画
+
+```java
+// Activity A
+Intent intent = new Intent(this, ActivityB.class);
+ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
+ this,
+ imageView, // 共享元素
+ "shared_image" // 共享元素名称
+);
+startActivity(intent, options.toBundle());
+
+// Activity B
+
+```
+
+### 自定义动画
+
+```xml
+
+
+
+
+```
+
+---
+
+## Activity最佳实践
+
+### 1. 避免内存泄漏
+
+```java
+// ❌ 错误:静态变量持有 Activity
+private static Activity sActivity;
+
+// ✅ 正确:使用 Application Context
+private static Context sContext = getApplicationContext();
+```
+
+### 2. 合理使用启动模式
+
+```java
+// 主界面使用 singleTask
+// 防止重复创建
+
+// 详情页使用 standard
+// 可以多个实例
+```
+
+### 3. 使用 ViewModel
+
+```java
+// 使用 ViewModel 保存数据
+// 避免在 onSaveInstanceState 中保存大量数据
+```
+
+### 4. 及时释放资源
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ // 释放资源
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Activity 生命周期?
+
+**答案:**
+onCreate → onStart → onResume → onPause → onStop → onDestroy
+onRestart(从 onStop 恢复时调用)
+
+### Q2: Activity 启动模式?
+
+**答案:**
+1. **standard**:每次创建新实例
+2. **singleTop**:栈顶复用
+3. **singleTask**:栈内复用
+4. **singleInstance**:单例模式
+
+### Q3: singleTask 和 singleInstance 的区别?
+
+**答案:**
+- **singleTask**:在同一个任务栈中复用
+- **singleInstance**:单独一个任务栈,全局唯一
+
+### Q4: Activity 重建时如何保存数据?
+
+**答案:**
+1. **onSaveInstanceState**:保存临时数据
+2. **ViewModel**:保存 UI 相关数据
+3. **持久化存储**:保存重要数据
+
+### Q5: Activity 和 Fragment 如何通信?
+
+**答案:**
+1. **接口回调**:Fragment 定义接口,Activity 实现
+2. **ViewModel**:共享数据
+3. **EventBus**:事件总线
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/核心组件/BroadcastReceiver详解.md b/docs/android面试/核心组件/BroadcastReceiver详解.md
new file mode 100644
index 0000000..4bcda7d
--- /dev/null
+++ b/docs/android面试/核心组件/BroadcastReceiver详解.md
@@ -0,0 +1,358 @@
+# BroadcastReceiver详解
+
+## 目录
+- [BroadcastReceiver类型](#broadcastreceiver类型)
+- [静态注册与动态注册](#静态注册与动态注册)
+- [有序广播与无序广播](#有序广播与无序广播)
+- [系统广播](#系统广播)
+- [自定义广播](#自定义广播)
+- [广播安全](#广播安全)
+- [BroadcastReceiver最佳实践](#broadcastreceiver最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## BroadcastReceiver类型
+
+### 普通广播接收器
+
+```java
+public class MyReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 处理广播
+ String action = intent.getAction();
+ if ("com.example.ACTION_CUSTOM".equals(action)) {
+ String data = intent.getStringExtra("data");
+ // 处理数据
+ }
+ }
+}
+```
+
+### 有序广播接收器
+
+```java
+// 可以设置优先级和结果
+public class OrderedReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 处理广播
+ setResultCode(Activity.RESULT_OK);
+ setResultData("Result Data");
+ }
+}
+```
+
+---
+
+## 静态注册与动态注册
+
+### 静态注册
+
+```xml
+
+
+
+
+
+
+```
+
+**特点:**
+- 应用安装时注册
+- 可以接收系统广播
+- 应用未运行也能接收
+- Android 8.0+ 限制静态注册
+
+### 动态注册
+
+```java
+public class MainActivity extends AppCompatActivity {
+ private BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 处理广播
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction("com.example.ACTION_CUSTOM");
+ registerReceiver(receiver, filter);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(receiver);
+ }
+}
+```
+
+**特点:**
+- 代码中注册
+- 需要应用运行
+- 必须手动注销
+- 更灵活
+
+---
+
+## 有序广播与无序广播
+
+### 无序广播
+
+```java
+// 发送无序广播
+Intent intent = new Intent("com.example.ACTION_BROADCAST");
+intent.putExtra("data", "value");
+sendBroadcast(intent);
+
+// 所有接收器同时接收
+// 无法中断广播
+```
+
+### 有序广播
+
+```java
+// 发送有序广播
+Intent intent = new Intent("com.example.ACTION_BROADCAST");
+intent.putExtra("data", "value");
+sendOrderedBroadcast(intent, null);
+
+// 接收器按优先级接收
+// 可以中断广播
+```
+
+### 优先级设置
+
+```xml
+
+
+
+
+
+
+```
+
+```java
+// 动态注册设置优先级
+IntentFilter filter = new IntentFilter("com.example.ACTION_BROADCAST");
+filter.setPriority(1000);
+registerReceiver(receiver, filter);
+```
+
+### 中断广播
+
+```java
+@Override
+public void onReceive(Context context, Intent intent) {
+ // 中断广播
+ abortBroadcast();
+
+ // 设置结果
+ setResultCode(Activity.RESULT_OK);
+ setResultData("Result");
+}
+```
+
+---
+
+## 系统广播
+
+### 常用系统广播
+
+```java
+// 开机完成
+Intent.ACTION_BOOT_COMPLETED
+
+// 网络状态变化
+ConnectivityManager.CONNECTIVITY_ACTION
+
+// 电池状态变化
+Intent.ACTION_BATTERY_CHANGED
+
+// 屏幕开启/关闭
+Intent.ACTION_SCREEN_ON
+Intent.ACTION_SCREEN_OFF
+
+// 应用安装/卸载
+Intent.ACTION_PACKAGE_ADDED
+Intent.ACTION_PACKAGE_REMOVED
+
+// 时间变化
+Intent.ACTION_TIME_TICK
+Intent.ACTION_TIME_CHANGED
+```
+
+### 系统广播接收
+
+```java
+// 接收开机广播
+public class BootReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ // 开机完成,启动服务
+ Intent serviceIntent = new Intent(context, MyService.class);
+ context.startService(serviceIntent);
+ }
+ }
+}
+```
+
+---
+
+## 自定义广播
+
+### 发送自定义广播
+
+```java
+// 发送无序广播
+Intent intent = new Intent("com.example.ACTION_CUSTOM");
+intent.putExtra("data", "value");
+sendBroadcast(intent);
+
+// 发送有序广播
+sendOrderedBroadcast(intent, null);
+
+// 发送本地广播(LocalBroadcastManager)
+LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+```
+
+### 接收自定义广播
+
+```java
+// 静态注册
+
+
+
+
+
+
+// 动态注册
+IntentFilter filter = new IntentFilter("com.example.ACTION_CUSTOM");
+registerReceiver(receiver, filter);
+```
+
+---
+
+## 广播安全
+
+### 安全措施
+
+#### 1. 限制广播接收
+
+```xml
+
+
+
+
+
+
+```
+
+#### 2. 使用权限
+
+```xml
+
+
+
+
+
+
+
+
+
+
+sendBroadcast(intent, "com.example.PERMISSION");
+```
+
+#### 3. 使用本地广播
+
+```java
+// LocalBroadcastManager:只能应用内接收
+LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+
+// 注册本地广播
+LocalBroadcastManager.getInstance(this)
+ .registerReceiver(receiver, filter);
+```
+
+---
+
+## BroadcastReceiver最佳实践
+
+### 1. 及时注销
+
+```java
+@Override
+protected void onDestroy() {
+ super.onDestroy();
+ if (receiver != null) {
+ unregisterReceiver(receiver);
+ }
+}
+```
+
+### 2. 避免耗时操作
+
+```java
+@Override
+public void onReceive(Context context, Intent intent) {
+ // ❌ 错误:在 onReceive 中执行耗时操作
+ // doHeavyWork();
+
+ // ✅ 正确:启动 Service 执行耗时操作
+ Intent serviceIntent = new Intent(context, MyService.class);
+ context.startService(serviceIntent);
+}
+```
+
+### 3. 使用 LocalBroadcastManager
+
+```java
+// 应用内通信使用本地广播
+LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 静态注册和动态注册的区别?
+
+**答案:**
+- **静态注册**:AndroidManifest.xml 中注册,应用安装时注册,可以接收系统广播
+- **动态注册**:代码中注册,需要应用运行,必须手动注销
+
+### Q2: 有序广播和无序广播的区别?
+
+**答案:**
+- **无序广播**:所有接收器同时接收,无法中断
+- **有序广播**:按优先级接收,可以中断
+
+### Q3: Android 8.0 对广播的限制?
+
+**答案:**
+- 限制静态注册大部分广播
+- 推荐使用动态注册
+- 使用 JobScheduler 或 WorkManager 替代
+
+### Q4: 广播安全措施?
+
+**答案:**
+1. 设置 `android:exported="false"`
+2. 使用权限保护
+3. 使用本地广播(LocalBroadcastManager)
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/核心组件/ContentProvider详解.md b/docs/android面试/核心组件/ContentProvider详解.md
new file mode 100644
index 0000000..e0c5647
--- /dev/null
+++ b/docs/android面试/核心组件/ContentProvider详解.md
@@ -0,0 +1,402 @@
+# ContentProvider详解
+
+## 目录
+- [ContentProvider作用](#contentprovider作用)
+- [URI机制](#uri机制)
+- [ContentResolver使用](#contentresolver使用)
+- [数据访问权限](#数据访问权限)
+- [ContentObserver](#contentobserver)
+- [ContentProvider实现](#contentprovider实现)
+- [ContentProvider最佳实践](#contentprovider最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## ContentProvider作用
+
+### 主要作用
+
+1. **数据共享**:应用间共享数据
+2. **数据封装**:封装数据访问逻辑
+3. **统一接口**:提供统一的数据访问接口
+4. **权限控制**:控制数据访问权限
+
+### 使用场景
+
+```java
+// 场景1:应用间共享数据
+// 应用A提供联系人数据
+// 应用B访问联系人数据
+
+// 场景2:封装数据访问
+// 统一管理数据库访问
+// 隐藏数据存储细节
+
+// 场景3:跨进程数据访问
+// 通过 Binder 机制跨进程访问
+```
+
+---
+
+## URI机制
+
+### URI 格式
+
+```java
+// URI 格式
+content://authority/path/id
+
+// 示例
+content://com.example.provider/user/1
+content://com.example.provider/user
+content://com.example.provider/user/1/name
+```
+
+### URI 组成
+
+```java
+// authority:ContentProvider 的标识
+// path:数据路径
+// id:数据ID(可选)
+
+// 解析 URI
+Uri uri = Uri.parse("content://com.example.provider/user/1");
+String authority = uri.getAuthority(); // com.example.provider
+List pathSegments = uri.getPathSegments(); // [user, 1]
+String id = uri.getLastPathSegment(); // 1
+```
+
+### URI 匹配
+
+```java
+// 使用 UriMatcher 匹配 URI
+private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+static {
+ uriMatcher.addURI("com.example.provider", "user", USER);
+ uriMatcher.addURI("com.example.provider", "user/#", USER_ID);
+}
+
+@Override
+public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ switch (uriMatcher.match(uri)) {
+ case USER:
+ // 查询所有用户
+ break;
+ case USER_ID:
+ // 查询指定用户
+ String id = uri.getLastPathSegment();
+ break;
+ }
+}
+```
+
+---
+
+## ContentResolver使用
+
+### 查询数据
+
+```java
+// 查询数据
+Uri uri = Uri.parse("content://com.example.provider/user");
+Cursor cursor = getContentResolver().query(
+ uri,
+ new String[]{"id", "name", "email"}, // projection
+ "age > ?", // selection
+ new String[]{"18"}, // selectionArgs
+ "name ASC" // sortOrder
+);
+
+if (cursor != null) {
+ while (cursor.moveToNext()) {
+ int id = cursor.getInt(cursor.getColumnIndex("id"));
+ String name = cursor.getString(cursor.getColumnIndex("name"));
+ String email = cursor.getString(cursor.getColumnIndex("email"));
+ }
+ cursor.close();
+}
+```
+
+### 插入数据
+
+```java
+// 插入数据
+Uri uri = Uri.parse("content://com.example.provider/user");
+ContentValues values = new ContentValues();
+values.put("name", "John");
+values.put("email", "john@example.com");
+Uri newUri = getContentResolver().insert(uri, values);
+```
+
+### 更新数据
+
+```java
+// 更新数据
+Uri uri = Uri.parse("content://com.example.provider/user/1");
+ContentValues values = new ContentValues();
+values.put("name", "Jane");
+int count = getContentResolver().update(uri, values, null, null);
+```
+
+### 删除数据
+
+```java
+// 删除数据
+Uri uri = Uri.parse("content://com.example.provider/user/1");
+int count = getContentResolver().delete(uri, null, null);
+```
+
+---
+
+## 数据访问权限
+
+### 权限声明
+
+```xml
+
+
+```
+
+### 权限检查
+
+```java
+public class MyProvider extends ContentProvider {
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ // 检查读取权限
+ if (getContext().checkCallingOrSelfPermission(
+ "com.example.READ_PERMISSION") != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Permission denied");
+ }
+ // 查询数据
+ return null;
+ }
+}
+```
+
+---
+
+## ContentObserver
+
+### ContentObserver 使用
+
+```java
+// 监听数据变化
+public class MyObserver extends ContentObserver {
+ public MyObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ // 数据变化时调用
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ // 指定 URI 的数据变化
+ }
+}
+
+// 注册观察者
+Uri uri = Uri.parse("content://com.example.provider/user");
+ContentObserver observer = new MyObserver(new Handler());
+getContentResolver().registerContentObserver(uri, true, observer);
+
+// 注销观察者
+getContentResolver().unregisterContentObserver(observer);
+```
+
+---
+
+## ContentProvider实现
+
+### 完整实现
+
+```java
+public class UserProvider extends ContentProvider {
+ private static final String AUTHORITY = "com.example.provider";
+ private static final String TABLE_USER = "user";
+
+ private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ private static final int USER = 1;
+ private static final int USER_ID = 2;
+
+ static {
+ uriMatcher.addURI(AUTHORITY, TABLE_USER, USER);
+ uriMatcher.addURI(AUTHORITY, TABLE_USER + "/#", USER_ID);
+ }
+
+ private SQLiteDatabase database;
+
+ @Override
+ public boolean onCreate() {
+ DatabaseHelper helper = new DatabaseHelper(getContext());
+ database = helper.getWritableDatabase();
+ return database != null;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
+ queryBuilder.setTables(TABLE_USER);
+
+ switch (uriMatcher.match(uri)) {
+ case USER:
+ break;
+ case USER_ID:
+ queryBuilder.appendWhere("id = " + uri.getLastPathSegment());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI: " + uri);
+ }
+
+ Cursor cursor = queryBuilder.query(database, projection, selection,
+ selectionArgs, null, null, sortOrder);
+ cursor.setNotificationUri(getContext().getContentResolver(), uri);
+ return cursor;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ long id = database.insert(TABLE_USER, null, values);
+ if (id > 0) {
+ Uri newUri = ContentUris.withAppendedId(uri, id);
+ getContext().getContentResolver().notifyChange(newUri, null);
+ return newUri;
+ }
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ int count;
+ switch (uriMatcher.match(uri)) {
+ case USER:
+ count = database.update(TABLE_USER, values, selection, selectionArgs);
+ break;
+ case USER_ID:
+ String id = uri.getLastPathSegment();
+ count = database.update(TABLE_USER, values, "id = ?", new String[]{id});
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI: " + uri);
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int count;
+ switch (uriMatcher.match(uri)) {
+ case USER:
+ count = database.delete(TABLE_USER, selection, selectionArgs);
+ break;
+ case USER_ID:
+ String id = uri.getLastPathSegment();
+ count = database.delete(TABLE_USER, "id = ?", new String[]{id});
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI: " + uri);
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ return count;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ switch (uriMatcher.match(uri)) {
+ case USER:
+ return "vnd.android.cursor.dir/user";
+ case USER_ID:
+ return "vnd.android.cursor.item/user";
+ default:
+ return null;
+ }
+ }
+}
+```
+
+---
+
+## ContentProvider最佳实践
+
+### 1. 通知数据变化
+
+```java
+// 数据变化时通知观察者
+getContext().getContentResolver().notifyChange(uri, null);
+```
+
+### 2. 使用事务
+
+```java
+database.beginTransaction();
+try {
+ // 批量操作
+ database.setTransactionSuccessful();
+} finally {
+ database.endTransaction();
+}
+```
+
+### 3. 权限控制
+
+```java
+// 检查权限
+if (getContext().checkCallingOrSelfPermission(permission)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Permission denied");
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: ContentProvider 的作用?
+
+**答案:**
+1. 数据共享:应用间共享数据
+2. 数据封装:封装数据访问逻辑
+3. 统一接口:提供统一的数据访问接口
+4. 权限控制:控制数据访问权限
+
+### Q2: URI 的格式?
+
+**答案:**
+`content://authority/path/id`
+- authority:ContentProvider 标识
+- path:数据路径
+- id:数据ID(可选)
+
+### Q3: ContentResolver 和 ContentProvider 的关系?
+
+**答案:**
+- **ContentResolver**:客户端,用于访问数据
+- **ContentProvider**:服务端,提供数据访问接口
+- 通过 URI 和 Binder 机制通信
+
+### Q4: ContentObserver 的作用?
+
+**答案:**
+- 监听 ContentProvider 数据变化
+- 数据变化时自动通知
+- 实现数据更新通知机制
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/核心组件/Fragment详解.md b/docs/android面试/核心组件/Fragment详解.md
new file mode 100644
index 0000000..6fa768b
--- /dev/null
+++ b/docs/android面试/核心组件/Fragment详解.md
@@ -0,0 +1,441 @@
+# Fragment详解
+
+## 目录
+- [Fragment生命周期](#fragment生命周期)
+- [Fragment与Activity通信](#fragment与activity通信)
+- [Fragment事务](#fragment事务)
+- [Fragment回退栈](#fragment回退栈)
+- [Fragment懒加载](#fragment懒加载)
+- [ViewPager与Fragment](#viewpager与fragment)
+- [Fragment最佳实践](#fragment最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Fragment生命周期
+
+### 生命周期方法
+
+```java
+public class MyFragment extends Fragment {
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ // Fragment 附加到 Activity
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Fragment 创建
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // 创建视图
+ return inflater.inflate(R.layout.fragment_my, container, false);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ // Activity 创建完成
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ // Fragment 可见
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // Fragment 可交互
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ // Fragment 失去焦点
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ // Fragment 不可见
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ // 销毁视图
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ // Fragment 销毁
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ // Fragment 从 Activity 分离
+ }
+}
+```
+
+### 生命周期流程图
+
+```
+附加到 Activity:
+onAttach() → onCreate() → onCreateView() → onActivityCreated()
+→ onStart() → onResume()
+
+切换到后台:
+onPause() → onStop()
+
+返回前台:
+onStart() → onResume()
+
+从 Activity 分离:
+onPause() → onStop() → onDestroyView() → onDestroy() → onDetach()
+```
+
+---
+
+## Fragment与Activity通信
+
+### 方式1:接口回调
+
+```java
+// Fragment 定义接口
+public class MyFragment extends Fragment {
+ public interface OnFragmentInteractionListener {
+ void onFragmentAction(String data);
+ }
+
+ private OnFragmentInteractionListener listener;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ if (context instanceof OnFragmentInteractionListener) {
+ listener = (OnFragmentInteractionListener) context;
+ }
+ }
+
+ private void sendDataToActivity() {
+ if (listener != null) {
+ listener.onFragmentAction("Data from Fragment");
+ }
+ }
+}
+
+// Activity 实现接口
+public class MainActivity extends AppCompatActivity
+ implements MyFragment.OnFragmentInteractionListener {
+
+ @Override
+ public void onFragmentAction(String data) {
+ // 处理数据
+ }
+}
+```
+
+### 方式2:ViewModel 共享
+
+```java
+// ViewModel
+public class SharedViewModel extends ViewModel {
+ private MutableLiveData data = new MutableLiveData<>();
+
+ public LiveData getData() {
+ return data;
+ }
+
+ public void setData(String value) {
+ data.setValue(value);
+ }
+}
+
+// Fragment A
+SharedViewModel viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
+viewModel.setData("Data from Fragment A");
+
+// Fragment B
+SharedViewModel viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
+viewModel.getData().observe(this, data -> {
+ // 接收数据
+});
+```
+
+### 方式3:Activity 方法调用
+
+```java
+// Activity 提供方法
+public class MainActivity extends AppCompatActivity {
+ public void updateData(String data) {
+ // 更新数据
+ }
+}
+
+// Fragment 调用
+((MainActivity) getActivity()).updateData("Data");
+```
+
+---
+
+## Fragment事务
+
+### Fragment 操作
+
+```java
+// 添加 Fragment
+FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+transaction.add(R.id.container, new MyFragment(), "tag");
+transaction.commit();
+
+// 替换 Fragment
+transaction.replace(R.id.container, new MyFragment());
+
+// 移除 Fragment
+transaction.remove(fragment);
+
+// 显示/隐藏 Fragment
+transaction.show(fragment);
+transaction.hide(fragment);
+
+// 添加动画
+transaction.setCustomAnimations(
+ R.anim.enter, R.anim.exit,
+ R.anim.pop_enter, R.anim.pop_exit
+);
+```
+
+### 事务提交
+
+```java
+// commit():异步提交
+transaction.commit();
+
+// commitNow():同步提交(立即执行)
+transaction.commitNow();
+
+// commitAllowingStateLoss():允许状态丢失时提交
+transaction.commitAllowingStateLoss();
+```
+
+---
+
+## Fragment回退栈
+
+### 回退栈使用
+
+```java
+// 添加到回退栈
+FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+transaction.replace(R.id.container, new FragmentB());
+transaction.addToBackStack("fragmentB");
+transaction.commit();
+
+// 按 Back 键会返回到上一个 Fragment
+```
+
+### 回退栈管理
+
+```java
+// 检查是否有回退栈
+if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
+ getSupportFragmentManager().popBackStack();
+}
+
+// 返回到指定 Fragment
+getSupportFragmentManager().popBackStack("fragmentA", 0);
+
+// 清空回退栈
+getSupportFragmentManager().popBackStack(null,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
+```
+
+---
+
+## Fragment懒加载
+
+### 懒加载实现
+
+```java
+public class LazyFragment extends Fragment {
+ private boolean isViewCreated = false;
+ private boolean isDataLoaded = false;
+
+ @Override
+ public void setUserVisibleHint(boolean isVisibleToUser) {
+ super.setUserVisibleHint(isVisibleToUser);
+ if (isVisibleToUser && isViewCreated && !isDataLoaded) {
+ loadData();
+ isDataLoaded = true;
+ }
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ isViewCreated = true;
+ if (getUserVisibleHint() && !isDataLoaded) {
+ loadData();
+ isDataLoaded = true;
+ }
+ }
+
+ private void loadData() {
+ // 加载数据
+ }
+}
+```
+
+### ViewPager2 懒加载
+
+```java
+// ViewPager2 使用 FragmentStateAdapter
+// 自动处理懒加载
+public class MyAdapter extends FragmentStateAdapter {
+ public MyAdapter(FragmentActivity activity) {
+ super(activity);
+ }
+
+ @Override
+ public Fragment createFragment(int position) {
+ return MyFragment.newInstance(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return 3;
+ }
+}
+```
+
+---
+
+## ViewPager与Fragment
+
+### ViewPager 使用
+
+```java
+// FragmentPagerAdapter:适合少量 Fragment
+public class MyPagerAdapter extends FragmentPagerAdapter {
+ private List fragments;
+
+ public MyPagerAdapter(FragmentManager fm, List fragments) {
+ super(fm);
+ this.fragments = fragments;
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ return fragments.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return fragments.size();
+ }
+}
+
+// FragmentStatePagerAdapter:适合大量 Fragment
+public class MyStateAdapter extends FragmentStatePagerAdapter {
+ // 实现类似
+}
+```
+
+### ViewPager2 使用
+
+```java
+// ViewPager2 推荐使用
+ViewPager2 viewPager = findViewById(R.id.viewPager);
+MyAdapter adapter = new MyAdapter(this);
+viewPager.setAdapter(adapter);
+
+// TabLayout 关联
+TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
+ tabLayout, viewPager, (tab, position) -> {
+ tab.setText("Tab " + position);
+ });
+tabLayoutMediator.attach();
+```
+
+---
+
+## Fragment最佳实践
+
+### 1. 使用 newInstance
+
+```java
+public class MyFragment extends Fragment {
+ public static MyFragment newInstance(String param) {
+ MyFragment fragment = new MyFragment();
+ Bundle args = new Bundle();
+ args.putString("param", param);
+ fragment.setArguments(args);
+ return fragment;
+ }
+}
+```
+
+### 2. 避免内存泄漏
+
+```java
+@Override
+public void onDestroyView() {
+ super.onDestroyView();
+ // 释放 View 相关资源
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ }
+}
+```
+
+### 3. 使用 ViewModel
+
+```java
+// 使用 ViewModel 保存数据
+// 避免在 onSaveInstanceState 中保存大量数据
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Fragment 生命周期?
+
+**答案:**
+onAttach → onCreate → onCreateView → onActivityCreated
+→ onStart → onResume → onPause → onStop
+→ onDestroyView → onDestroy → onDetach
+
+### Q2: Fragment 和 Activity 的区别?
+
+**答案:**
+- **Activity**:独立的界面,可以单独存在
+- **Fragment**:必须依附于 Activity,是 Activity 的一部分
+
+### Q3: Fragment 事务?
+
+**答案:**
+- 使用 FragmentTransaction 进行 Fragment 操作
+- 可以添加、替换、移除 Fragment
+- 可以添加到回退栈
+
+### Q4: Fragment 懒加载?
+
+**答案:**
+- 只在 Fragment 可见时加载数据
+- 使用 setUserVisibleHint 或 onViewCreated
+- 提升性能,减少不必要的加载
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/核心组件/Intent详解.md b/docs/android面试/核心组件/Intent详解.md
new file mode 100644
index 0000000..3556959
--- /dev/null
+++ b/docs/android面试/核心组件/Intent详解.md
@@ -0,0 +1,338 @@
+# Intent详解
+
+## 目录
+- [Intent类型](#intent类型)
+- [Intent组件](#intent组件)
+- [Intent过滤器](#intent过滤器)
+- [Intent传递数据](#intent传递数据)
+- [Intent Flag](#intent-flag)
+- [隐式Intent与显式Intent](#隐式intent与显式intent)
+- [Intent最佳实践](#intent最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Intent类型
+
+### 显式 Intent
+
+```java
+// 显式 Intent:明确指定目标组件
+Intent intent = new Intent(this, MainActivity.class);
+startActivity(intent);
+
+// 或
+Intent intent = new Intent();
+intent.setComponent(new ComponentName(this, MainActivity.class));
+startActivity(intent);
+```
+
+### 隐式 Intent
+
+```java
+// 隐式 Intent:通过 Action 和 Category 匹配
+Intent intent = new Intent(Intent.ACTION_VIEW);
+intent.setData(Uri.parse("https://www.example.com"));
+startActivity(intent);
+```
+
+---
+
+## Intent组件
+
+### ComponentName
+
+```java
+// 指定组件
+Intent intent = new Intent();
+intent.setComponent(new ComponentName("com.example.package",
+ "com.example.package.MainActivity"));
+startActivity(intent);
+
+// 或
+ComponentName component = new ComponentName(this, MainActivity.class);
+Intent intent = new Intent();
+intent.setComponent(component);
+startActivity(intent);
+```
+
+### Class
+
+```java
+// 直接指定类
+Intent intent = new Intent(this, MainActivity.class);
+startActivity(intent);
+```
+
+---
+
+## Intent过滤器
+
+### IntentFilter 配置
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Action
+
+```java
+// 常用 Action
+Intent.ACTION_VIEW // 查看
+Intent.ACTION_SEND // 发送
+Intent.ACTION_EDIT // 编辑
+Intent.ACTION_DIAL // 拨号
+Intent.ACTION_CALL // 打电话
+Intent.ACTION_PICK // 选择
+Intent.ACTION_GET_CONTENT // 获取内容
+```
+
+### Category
+
+```java
+// 常用 Category
+Intent.CATEGORY_DEFAULT // 默认
+Intent.CATEGORY_LAUNCHER // 启动器
+Intent.CATEGORY_BROWSABLE // 可浏览
+Intent.CATEGORY_OPENABLE // 可打开
+```
+
+### Data
+
+```java
+// Data 匹配
+
+
+// 使用
+Intent intent = new Intent(Intent.ACTION_VIEW);
+intent.setData(Uri.parse("https://www.example.com/path"));
+startActivity(intent);
+```
+
+---
+
+## Intent传递数据
+
+### 基本数据类型
+
+```java
+// 传递基本数据
+Intent intent = new Intent(this, MainActivity.class);
+intent.putExtra("name", "John");
+intent.putExtra("age", 25);
+intent.putExtra("isVip", true);
+startActivity(intent);
+
+// 接收数据
+String name = getIntent().getStringExtra("name");
+int age = getIntent().getIntExtra("age", 0);
+boolean isVip = getIntent().getBooleanExtra("isVip", false);
+```
+
+### 对象数据
+
+```java
+// 传递对象(实现 Parcelable)
+public class User implements Parcelable {
+ private String name;
+ private int age;
+
+ // Parcelable 实现
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(name);
+ dest.writeInt(age);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public User createFromParcel(Parcel in) {
+ return new User(in);
+ }
+
+ @Override
+ public User[] newArray(int size) {
+ return new User[size];
+ }
+ };
+}
+
+// 传递
+Intent intent = new Intent(this, MainActivity.class);
+intent.putExtra("user", user);
+startActivity(intent);
+
+// 接收
+User user = getIntent().getParcelableExtra("user");
+```
+
+### Bundle
+
+```java
+// 使用 Bundle
+Bundle bundle = new Bundle();
+bundle.putString("name", "John");
+bundle.putInt("age", 25);
+intent.putExtras(bundle);
+
+// 接收
+Bundle bundle = getIntent().getExtras();
+String name = bundle.getString("name");
+```
+
+---
+
+## Intent Flag
+
+### 常用 Flag
+
+```java
+// FLAG_ACTIVITY_NEW_TASK:在新任务栈中启动
+intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+// FLAG_ACTIVITY_SINGLE_TOP:等同于 singleTop
+intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+
+// FLAG_ACTIVITY_CLEAR_TOP:清除栈顶 Activity
+intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+// FLAG_ACTIVITY_CLEAR_TASK:清除整个任务栈
+intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+// FLAG_ACTIVITY_NO_HISTORY:不加入历史栈
+intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+
+// 组合使用
+intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+```
+
+---
+
+## 隐式Intent与显式Intent
+
+### 显式 Intent
+
+```java
+// 优点:明确、快速
+// 缺点:耦合度高
+Intent intent = new Intent(this, MainActivity.class);
+startActivity(intent);
+```
+
+### 隐式 Intent
+
+```java
+// 优点:解耦、灵活
+// 缺点:可能匹配多个组件
+Intent intent = new Intent(Intent.ACTION_VIEW);
+intent.setData(Uri.parse("https://www.example.com"));
+startActivity(intent);
+```
+
+### 选择建议
+
+```java
+// 应用内跳转 → 显式 Intent
+Intent intent = new Intent(this, MainActivity.class);
+
+// 调用系统功能 → 隐式 Intent
+Intent intent = new Intent(Intent.ACTION_DIAL);
+intent.setData(Uri.parse("tel:10086"));
+
+// 应用间跳转 → 隐式 Intent(需要明确包名时用显式)
+Intent intent = new Intent("com.example.ACTION_VIEW");
+```
+
+---
+
+## Intent最佳实践
+
+### 1. 数据大小限制
+
+```java
+// ❌ 错误:传递大量数据
+intent.putExtra("largeData", largeByteArray); // 可能失败
+
+// ✅ 正确:传递数据引用
+intent.putExtra("dataId", dataId);
+// 通过 ID 获取数据
+```
+
+### 2. 使用 Parcelable
+
+```java
+// ✅ 推荐:实现 Parcelable
+public class User implements Parcelable {
+ // 实现 Parcelable
+}
+
+// ❌ 不推荐:实现 Serializable(性能差)
+public class User implements Serializable {
+ // 实现 Serializable
+}
+```
+
+### 3. 检查 Intent 是否可用
+
+```java
+// 检查 Intent 是否可用
+Intent intent = new Intent(Intent.ACTION_VIEW);
+intent.setData(Uri.parse("https://www.example.com"));
+if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(intent);
+} else {
+ // 处理没有可用组件的情况
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Intent 的作用?
+
+**答案:**
+1. **启动组件**:启动 Activity、Service、BroadcastReceiver
+2. **传递数据**:组件间传递数据
+3. **组件通信**:应用内和应用间通信
+
+### Q2: 显式 Intent 和隐式 Intent 的区别?
+
+**答案:**
+- **显式 Intent**:明确指定目标组件,直接启动
+- **隐式 Intent**:通过 Action、Category、Data 匹配,系统选择组件
+
+### Q3: Intent Filter 的匹配规则?
+
+**答案:**
+1. **Action**:必须匹配
+2. **Category**:Intent 中的 Category 必须在 Filter 中存在
+3. **Data**:scheme、host、path、mimeType 必须匹配
+
+### Q4: Intent 传递数据的方式?
+
+**答案:**
+1. **putExtra**:传递基本数据类型
+2. **putParcelable**:传递 Parcelable 对象
+3. **putSerializable**:传递 Serializable 对象(不推荐)
+4. **Bundle**:使用 Bundle 传递多个数据
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/核心组件/Service详解.md b/docs/android面试/核心组件/Service详解.md
new file mode 100644
index 0000000..d405993
--- /dev/null
+++ b/docs/android面试/核心组件/Service详解.md
@@ -0,0 +1,404 @@
+# Service详解
+
+## 目录
+- [Service生命周期](#service生命周期)
+- [Service类型](#service类型)
+- [IntentService](#intentservice)
+- [Service与Activity通信](#service与activity通信)
+- [Service保活](#service保活)
+- [Service最佳实践](#service最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Service生命周期
+
+### 普通 Service 生命周期
+
+```java
+public class MyService extends Service {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ // Service 创建时调用
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // Service 启动时调用(startService)
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // Service 绑定时调用(bindService)
+ return binder;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ // Service 销毁时调用
+ }
+}
+```
+
+### 绑定 Service 生命周期
+
+```java
+// 绑定 Service
+bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+
+// 解绑 Service
+unbindService(serviceConnection);
+
+// 生命周期
+// onCreate() → onBind() → onUnbind() → onDestroy()
+```
+
+---
+
+## Service类型
+
+### 1. 普通 Service
+
+```java
+// 普通 Service:后台执行任务
+public class MyService extends Service {
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // 执行任务
+ new Thread(() -> {
+ // 耗时操作
+ }).start();
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+}
+```
+
+### 2. 前台 Service
+
+```java
+// 前台 Service:显示通知
+public class ForegroundService extends Service {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
+ .setContentTitle("服务运行中")
+ .setContentText("正在执行任务")
+ .setSmallIcon(R.drawable.ic_notification)
+ .build();
+
+ startForeground(1, notification);
+ }
+}
+```
+
+### 3. 绑定 Service
+
+```java
+// 绑定 Service:与 Activity 通信
+public class BoundService extends Service {
+ private IBinder binder = new LocalBinder();
+
+ public class LocalBinder extends Binder {
+ BoundService getService() {
+ return BoundService.this;
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return binder;
+ }
+
+ public void doSomething() {
+ // Service 方法
+ }
+}
+
+// Activity 中使用
+private ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ BoundService.LocalBinder binder = (BoundService.LocalBinder) service;
+ boundService = binder.getService();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ boundService = null;
+ }
+};
+```
+
+---
+
+## IntentService
+
+### IntentService 特点
+
+```java
+// IntentService:自动在后台线程执行任务
+public class MyIntentService extends IntentService {
+ public MyIntentService() {
+ super("MyIntentService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // 在后台线程执行
+ // 任务执行完毕后自动停止
+ String action = intent.getAction();
+ if ("ACTION_DOWNLOAD".equals(action)) {
+ downloadFile();
+ }
+ }
+}
+
+// 启动
+Intent intent = new Intent(this, MyIntentService.class);
+intent.setAction("ACTION_DOWNLOAD");
+startService(intent);
+```
+
+### IntentService vs Service
+
+| 特性 | Service | IntentService |
+|------|---------|---------------|
+| 线程 | 主线程 | 后台线程 |
+| 自动停止 | 否 | 是 |
+| 多任务 | 需要手动处理 | 自动排队 |
+| 适用场景 | 需要长期运行 | 一次性任务 |
+
+---
+
+## Service与Activity通信
+
+### 方式1:Binder
+
+```java
+// Service
+public class MyService extends Service {
+ private IBinder binder = new LocalBinder();
+
+ public class LocalBinder extends Binder {
+ MyService getService() {
+ return MyService.this;
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return binder;
+ }
+
+ public void doWork() {
+ // Service 方法
+ }
+}
+
+// Activity
+private ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ MyService.LocalBinder binder = (MyService.LocalBinder) service;
+ myService = binder.getService();
+ myService.doWork();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ myService = null;
+ }
+};
+
+bindService(intent, connection, Context.BIND_AUTO_CREATE);
+```
+
+### 方式2:BroadcastReceiver
+
+```java
+// Service 发送广播
+Intent broadcast = new Intent("ACTION_UPDATE");
+broadcast.putExtra("data", "value");
+sendBroadcast(broadcast);
+
+// Activity 接收广播
+private BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String data = intent.getStringExtra("data");
+ }
+};
+
+registerReceiver(receiver, new IntentFilter("ACTION_UPDATE"));
+```
+
+### 方式3:Messenger
+
+```java
+// Service
+public class MessengerService extends Service {
+ private Messenger messenger = new Messenger(new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // 处理消息
+ }
+ });
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return messenger.getBinder();
+ }
+}
+
+// Activity
+private Messenger serviceMessenger;
+
+private ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ serviceMessenger = new Messenger(service);
+
+ Message msg = Message.obtain();
+ msg.what = 1;
+ msg.obj = "Data";
+ try {
+ serviceMessenger.send(msg);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ serviceMessenger = null;
+ }
+};
+```
+
+---
+
+## Service保活
+
+### 保活方式
+
+#### 1. 前台 Service
+
+```java
+// 使用前台 Service
+startForeground(1, notification);
+```
+
+#### 2. 双进程守护
+
+```java
+// 两个进程互相守护
+// 进程1:主进程
+// 进程2:守护进程
+```
+
+#### 3. JobScheduler
+
+```java
+// 使用 JobScheduler 定时启动
+JobInfo jobInfo = new JobInfo.Builder(1, componentName)
+ .setPeriodic(15 * 60 * 1000)
+ .build();
+jobScheduler.schedule(jobInfo);
+```
+
+### 注意事项
+
+```java
+// ❌ 不推荐:过度保活
+// 1. 影响用户体验
+// 2. 消耗电量
+// 3. 可能被系统杀死
+
+// ✅ 推荐:合理使用
+// 1. 使用前台 Service(重要任务)
+// 2. 使用 JobScheduler(定时任务)
+// 3. 使用 WorkManager(后台任务)
+```
+
+---
+
+## Service最佳实践
+
+### 1. 及时停止 Service
+
+```java
+// 任务完成后及时停止
+@Override
+protected void onHandleIntent(Intent intent) {
+ // 执行任务
+ doWork();
+ // 任务完成后自动停止
+}
+```
+
+### 2. 避免内存泄漏
+
+```java
+@Override
+public void onDestroy() {
+ super.onDestroy();
+ // 释放资源
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ }
+}
+```
+
+### 3. 合理选择 Service 类型
+
+```java
+// 长期运行 → 前台 Service
+// 一次性任务 → IntentService
+// 需要通信 → 绑定 Service
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Service 生命周期?
+
+**答案:**
+- **启动 Service**:onCreate() → onStartCommand() → onDestroy()
+- **绑定 Service**:onCreate() → onBind() → onUnbind() → onDestroy()
+
+### Q2: Service 和 Thread 的区别?
+
+**答案:**
+- **Service**:运行在主线程,是 Android 组件
+- **Thread**:后台线程,不是 Android 组件
+- **使用**:Service 中创建 Thread 执行耗时操作
+
+### Q3: IntentService 的特点?
+
+**答案:**
+1. 自动在后台线程执行
+2. 任务执行完毕后自动停止
+3. 多个任务自动排队执行
+
+### Q4: Service 保活方式?
+
+**答案:**
+1. 前台 Service
+2. 双进程守护
+3. JobScheduler
+4. WorkManager
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/动态规划.md b/docs/android面试/算法与数据结构/动态规划.md
new file mode 100644
index 0000000..5a1cd59
--- /dev/null
+++ b/docs/android面试/算法与数据结构/动态规划.md
@@ -0,0 +1,103 @@
+# 动态规划
+
+## 目录
+- [动态规划概念](#动态规划概念)
+- [动态规划步骤](#动态规划步骤)
+- [经典问题](#经典问题)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 动态规划概念
+
+### 定义
+
+```java
+// 动态规划:将问题分解为子问题
+// 保存子问题的解,避免重复计算
+// 自底向上求解
+```
+
+### 适用场景
+
+```java
+// 1. 最优子结构
+// 2. 重叠子问题
+// 3. 无后效性
+```
+
+---
+
+## 动态规划步骤
+
+### 步骤
+
+```java
+// 1. 定义状态
+// 2. 状态转移方程
+// 3. 初始状态
+// 4. 计算顺序
+```
+
+---
+
+## 经典问题
+
+### 题1:斐波那契数列
+
+```java
+// 递归(低效)
+public int fib(int n) {
+ if (n <= 1) return n;
+ return fib(n - 1) + fib(n - 2);
+}
+
+// 动态规划
+public int fibDP(int n) {
+ if (n <= 1) return n;
+ int[] dp = new int[n + 1];
+ dp[0] = 0;
+ dp[1] = 1;
+ for (int i = 2; i <= n; i++) {
+ dp[i] = dp[i - 1] + dp[i - 2];
+ }
+ return dp[n];
+}
+```
+
+### 题2:爬楼梯
+
+```java
+// 每次可以爬 1 或 2 步,有多少种方法
+public int climbStairs(int n) {
+ if (n <= 2) return n;
+ int[] dp = new int[n + 1];
+ dp[1] = 1;
+ dp[2] = 2;
+ for (int i = 3; i <= n; i++) {
+ dp[i] = dp[i - 1] + dp[i - 2];
+ }
+ return dp[n];
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 动态规划的特点?
+
+**答案:**
+- 最优子结构
+- 重叠子问题
+- 自底向上求解
+
+### Q2: 动态规划和递归的区别?
+
+**答案:**
+- **递归**:自顶向下,可能重复计算
+- **动态规划**:自底向上,避免重复计算
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/字符串算法.md b/docs/android面试/算法与数据结构/字符串算法.md
new file mode 100644
index 0000000..b05edda
--- /dev/null
+++ b/docs/android面试/算法与数据结构/字符串算法.md
@@ -0,0 +1,117 @@
+# 字符串算法
+
+## 目录
+- [字符串基础](#字符串基础)
+- [常见操作](#常见操作)
+- [字符串匹配](#字符串匹配)
+- [算法题](#算法题)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 字符串基础
+
+### 字符串操作
+
+```java
+// 1. 长度
+String str = "Hello";
+int len = str.length(); // 5
+
+// 2. 查找
+int index = str.indexOf("l"); // 2
+
+// 3. 截取
+String sub = str.substring(1, 3); // "el"
+
+// 4. 替换
+String newStr = str.replace("l", "L"); // "HeLLo"
+```
+
+---
+
+## 常见操作
+
+### 反转字符串
+
+```java
+public String reverse(String s) {
+ char[] chars = s.toCharArray();
+ int left = 0, right = chars.length - 1;
+ while (left < right) {
+ char temp = chars[left];
+ chars[left] = chars[right];
+ chars[right] = temp;
+ left++;
+ right--;
+ }
+ return new String(chars);
+}
+```
+
+### 判断回文
+
+```java
+public boolean isPalindrome(String s) {
+ int left = 0, right = s.length() - 1;
+ while (left < right) {
+ if (s.charAt(left) != s.charAt(right)) {
+ return false;
+ }
+ left++;
+ right--;
+ }
+ return true;
+}
+```
+
+---
+
+## 字符串匹配
+
+### KMP 算法
+
+```java
+// KMP:高效的字符串匹配算法
+// 时间复杂度:O(n + m)
+```
+
+---
+
+## 算法题
+
+### 题1:最长公共前缀
+
+```java
+public String longestCommonPrefix(String[] strs) {
+ if (strs.length == 0) return "";
+ String prefix = strs[0];
+ for (int i = 1; i < strs.length; i++) {
+ while (strs[i].indexOf(prefix) != 0) {
+ prefix = prefix.substring(0, prefix.length() - 1);
+ if (prefix.isEmpty()) return "";
+ }
+ }
+ return prefix;
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 字符串反转?
+
+**答案:**
+- 使用双指针
+- 从两端向中间交换
+
+### Q2: 判断回文?
+
+**答案:**
+- 双指针比较
+- 从两端向中间
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/排序算法.md b/docs/android面试/算法与数据结构/排序算法.md
new file mode 100644
index 0000000..ca9f0ba
--- /dev/null
+++ b/docs/android面试/算法与数据结构/排序算法.md
@@ -0,0 +1,275 @@
+# 排序算法
+
+## 目录
+- [冒泡排序](#冒泡排序)
+- [选择排序](#选择排序)
+- [插入排序](#插入排序)
+- [快速排序](#快速排序)
+- [归并排序](#归并排序)
+- [堆排序](#堆排序)
+- [算法复杂度分析](#算法复杂度分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 冒泡排序
+
+### 算法实现
+
+```java
+public void bubbleSort(int[] arr) {
+ int n = arr.length;
+ for (int i = 0; i < n - 1; i++) {
+ for (int j = 0; j < n - 1 - i; j++) {
+ if (arr[j] > arr[j + 1]) {
+ int temp = arr[j];
+ arr[j] = arr[j + 1];
+ arr[j + 1] = temp;
+ }
+ }
+ }
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(n²)
+// 空间复杂度:O(1)
+// 稳定性:稳定
+```
+
+---
+
+## 选择排序
+
+### 算法实现
+
+```java
+public void selectionSort(int[] arr) {
+ int n = arr.length;
+ for (int i = 0; i < n - 1; i++) {
+ int minIndex = i;
+ for (int j = i + 1; j < n; j++) {
+ if (arr[j] < arr[minIndex]) {
+ minIndex = j;
+ }
+ }
+ int temp = arr[i];
+ arr[i] = arr[minIndex];
+ arr[minIndex] = temp;
+ }
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(n²)
+// 空间复杂度:O(1)
+// 稳定性:不稳定
+```
+
+---
+
+## 插入排序
+
+### 算法实现
+
+```java
+public void insertionSort(int[] arr) {
+ int n = arr.length;
+ for (int i = 1; i < n; i++) {
+ int key = arr[i];
+ int j = i - 1;
+ while (j >= 0 && arr[j] > key) {
+ arr[j + 1] = arr[j];
+ j--;
+ }
+ arr[j + 1] = key;
+ }
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(n²)
+// 空间复杂度:O(1)
+// 稳定性:稳定
+```
+
+---
+
+## 快速排序
+
+### 算法实现
+
+```java
+public void quickSort(int[] arr, int low, int high) {
+ if (low < high) {
+ int pivot = partition(arr, low, high);
+ quickSort(arr, low, pivot - 1);
+ quickSort(arr, pivot + 1, high);
+ }
+}
+
+private int partition(int[] arr, int low, int high) {
+ int pivot = arr[high];
+ int i = low - 1;
+ for (int j = low; j < high; j++) {
+ if (arr[j] < pivot) {
+ i++;
+ int temp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = temp;
+ }
+ }
+ int temp = arr[i + 1];
+ arr[i + 1] = arr[high];
+ arr[high] = temp;
+ return i + 1;
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:平均 O(n log n),最坏 O(n²)
+// 空间复杂度:O(log n)
+// 稳定性:不稳定
+```
+
+---
+
+## 归并排序
+
+### 算法实现
+
+```java
+public void mergeSort(int[] arr, int left, int right) {
+ if (left < right) {
+ int mid = (left + right) / 2;
+ mergeSort(arr, left, mid);
+ mergeSort(arr, mid + 1, right);
+ merge(arr, left, mid, right);
+ }
+}
+
+private void merge(int[] arr, int left, int mid, int right) {
+ int[] temp = new int[right - left + 1];
+ int i = left, j = mid + 1, k = 0;
+ while (i <= mid && j <= right) {
+ if (arr[i] <= arr[j]) {
+ temp[k++] = arr[i++];
+ } else {
+ temp[k++] = arr[j++];
+ }
+ }
+ while (i <= mid) temp[k++] = arr[i++];
+ while (j <= right) temp[k++] = arr[j++];
+ for (i = left; i <= right; i++) {
+ arr[i] = temp[i - left];
+ }
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(n log n)
+// 空间复杂度:O(n)
+// 稳定性:稳定
+```
+
+---
+
+## 堆排序
+
+### 算法实现
+
+```java
+public void heapSort(int[] arr) {
+ int n = arr.length;
+ // 构建堆
+ for (int i = n / 2 - 1; i >= 0; i--) {
+ heapify(arr, n, i);
+ }
+ // 逐个取出堆顶
+ for (int i = n - 1; i > 0; i--) {
+ int temp = arr[0];
+ arr[0] = arr[i];
+ arr[i] = temp;
+ heapify(arr, i, 0);
+ }
+}
+
+private void heapify(int[] arr, int n, int i) {
+ int largest = i;
+ int left = 2 * i + 1;
+ int right = 2 * i + 2;
+ if (left < n && arr[left] > arr[largest]) {
+ largest = left;
+ }
+ if (right < n && arr[right] > arr[largest]) {
+ largest = right;
+ }
+ if (largest != i) {
+ int temp = arr[i];
+ arr[i] = arr[largest];
+ arr[largest] = temp;
+ heapify(arr, n, largest);
+ }
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(n log n)
+// 空间复杂度:O(1)
+// 稳定性:不稳定
+```
+
+---
+
+## 算法复杂度分析
+
+### 对比表
+
+| 算法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
+|------|---------------|---------------|-----------|--------|
+| 冒泡排序 | O(n²) | O(n²) | O(1) | 稳定 |
+| 选择排序 | O(n²) | O(n²) | O(1) | 不稳定 |
+| 插入排序 | O(n²) | O(n²) | O(1) | 稳定 |
+| 快速排序 | O(n log n) | O(n²) | O(log n) | 不稳定 |
+| 归并排序 | O(n log n) | O(n log n) | O(n) | 稳定 |
+| 堆排序 | O(n log n) | O(n log n) | O(1) | 不稳定 |
+
+---
+
+## 面试常见问题
+
+### Q1: 快速排序的原理?
+
+**答案:**
+- 选择基准元素
+- 分区:小于基准的在左,大于基准的在右
+- 递归排序左右两部分
+
+### Q2: 归并排序和快速排序的区别?
+
+**答案:**
+- **归并排序**:稳定,O(n) 空间,平均和最坏都是 O(n log n)
+- **快速排序**:不稳定,O(log n) 空间,平均 O(n log n),最坏 O(n²)
+
+### Q3: 什么时候用哪种排序?
+
+**答案:**
+- **快速排序**:一般情况,性能好
+- **归并排序**:需要稳定排序
+- **堆排序**:需要原地排序
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/数组与链表.md b/docs/android面试/算法与数据结构/数组与链表.md
new file mode 100644
index 0000000..92f6567
--- /dev/null
+++ b/docs/android面试/算法与数据结构/数组与链表.md
@@ -0,0 +1,241 @@
+# 数组与链表
+
+## 目录
+- [数组基础](#数组基础)
+- [链表基础](#链表基础)
+- [数组与链表对比](#数组与链表对比)
+- [常见操作](#常见操作)
+- [算法题](#算法题)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 数组基础
+
+### 数组定义
+
+```java
+// 数组:连续的内存空间存储相同类型的数据
+int[] arr = new int[10];
+String[] strs = {"a", "b", "c"};
+```
+
+### 数组特点
+
+```java
+// 优点:
+// 1. 随机访问快:O(1)
+// 2. 内存连续,缓存友好
+
+// 缺点:
+// 1. 插入删除慢:O(n)
+// 2. 大小固定
+```
+
+### 数组操作
+
+```java
+// 访问
+int value = arr[0]; // O(1)
+
+// 插入
+// 需要移动元素:O(n)
+
+// 删除
+// 需要移动元素:O(n)
+
+// 查找
+// 遍历查找:O(n)
+// 有序数组二分查找:O(log n)
+```
+
+---
+
+## 链表基础
+
+### 链表定义
+
+```java
+// 链表:非连续的内存空间,通过指针连接
+public class ListNode {
+ int val;
+ ListNode next;
+
+ ListNode(int val) {
+ this.val = val;
+ }
+}
+```
+
+### 链表类型
+
+```java
+// 1. 单链表
+public class ListNode {
+ int val;
+ ListNode next;
+}
+
+// 2. 双链表
+public class DoublyListNode {
+ int val;
+ DoublyListNode prev;
+ DoublyListNode next;
+}
+
+// 3. 循环链表
+// 尾节点指向头节点
+```
+
+### 链表特点
+
+```java
+// 优点:
+// 1. 插入删除快:O(1)
+// 2. 动态大小
+
+// 缺点:
+// 1. 随机访问慢:O(n)
+// 2. 内存不连续,缓存不友好
+```
+
+---
+
+## 数组与链表对比
+
+### 对比表
+
+| 特性 | 数组 | 链表 |
+|------|------|------|
+| 内存 | 连续 | 非连续 |
+| 访问 | O(1) | O(n) |
+| 插入 | O(n) | O(1) |
+| 删除 | O(n) | O(1) |
+| 大小 | 固定 | 动态 |
+
+---
+
+## 常见操作
+
+### 数组操作
+
+```java
+// 1. 反转数组
+public void reverse(int[] arr) {
+ int left = 0, right = arr.length - 1;
+ while (left < right) {
+ int temp = arr[left];
+ arr[left] = arr[right];
+ arr[right] = temp;
+ left++;
+ right--;
+ }
+}
+
+// 2. 查找最大值
+public int findMax(int[] arr) {
+ int max = arr[0];
+ for (int i = 1; i < arr.length; i++) {
+ if (arr[i] > max) {
+ max = arr[i];
+ }
+ }
+ return max;
+}
+```
+
+### 链表操作
+
+```java
+// 1. 反转链表
+public ListNode reverseList(ListNode head) {
+ ListNode prev = null;
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = prev;
+ prev = curr;
+ curr = next;
+ }
+ return prev;
+}
+
+// 2. 查找中间节点
+public ListNode findMiddle(ListNode head) {
+ ListNode slow = head;
+ ListNode fast = head;
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+ return slow;
+}
+```
+
+---
+
+## 算法题
+
+### 题1:两数之和
+
+```java
+// 给定数组和目标值,找出两数之和等于目标值
+public int[] twoSum(int[] nums, int target) {
+ Map map = new HashMap<>();
+ for (int i = 0; i < nums.length; i++) {
+ int complement = target - nums[i];
+ if (map.containsKey(complement)) {
+ return new int[]{map.get(complement), i};
+ }
+ map.put(nums[i], i);
+ }
+ return new int[]{};
+}
+```
+
+### 题2:合并两个有序链表
+
+```java
+public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
+ ListNode dummy = new ListNode(0);
+ ListNode curr = dummy;
+ while (l1 != null && l2 != null) {
+ if (l1.val < l2.val) {
+ curr.next = l1;
+ l1 = l1.next;
+ } else {
+ curr.next = l2;
+ l2 = l2.next;
+ }
+ curr = curr.next;
+ }
+ curr.next = l1 != null ? l1 : l2;
+ return dummy.next;
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 数组和链表的区别?
+
+**答案:**
+- **数组**:连续内存,随机访问快,插入删除慢
+- **链表**:非连续内存,插入删除快,随机访问慢
+
+### Q2: 什么时候用数组,什么时候用链表?
+
+**答案:**
+- **数组**:需要随机访问,数据大小固定
+- **链表**:需要频繁插入删除,数据大小动态
+
+### Q3: 如何反转链表?
+
+**答案:**
+- 使用三个指针:prev、curr、next
+- 遍历链表,逐个反转指针
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/查找算法.md b/docs/android面试/算法与数据结构/查找算法.md
new file mode 100644
index 0000000..c68ac25
--- /dev/null
+++ b/docs/android面试/算法与数据结构/查找算法.md
@@ -0,0 +1,118 @@
+# 查找算法
+
+## 目录
+- [顺序查找](#顺序查找)
+- [二分查找](#二分查找)
+- [哈希查找](#哈希查找)
+- [算法复杂度分析](#算法复杂度分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 顺序查找
+
+### 算法实现
+
+```java
+public int linearSearch(int[] arr, int target) {
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i] == target) {
+ return i;
+ }
+ }
+ return -1;
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(n)
+// 空间复杂度:O(1)
+```
+
+---
+
+## 二分查找
+
+### 算法实现
+
+```java
+public int binarySearch(int[] arr, int target) {
+ int left = 0, right = arr.length - 1;
+ while (left <= right) {
+ int mid = left + (right - left) / 2;
+ if (arr[mid] == target) {
+ return mid;
+ } else if (arr[mid] < target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+ return -1;
+}
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:O(log n)
+// 空间复杂度:O(1)
+// 要求:数组必须有序
+```
+
+---
+
+## 哈希查找
+
+### 算法实现
+
+```java
+// 使用 HashMap
+Map map = new HashMap<>();
+map.put(1, 10);
+map.put(2, 20);
+
+int value = map.get(1); // O(1)
+```
+
+### 复杂度
+
+```java
+// 时间复杂度:平均 O(1),最坏 O(n)
+// 空间复杂度:O(n)
+```
+
+---
+
+## 算法复杂度分析
+
+### 对比表
+
+| 算法 | 时间复杂度 | 空间复杂度 | 要求 |
+|------|-----------|-----------|------|
+| 顺序查找 | O(n) | O(1) | 无 |
+| 二分查找 | O(log n) | O(1) | 有序 |
+| 哈希查找 | O(1) | O(n) | 无 |
+
+---
+
+## 面试常见问题
+
+### Q1: 二分查找的条件?
+
+**答案:**
+- 数组必须有序
+- 时间复杂度 O(log n)
+
+### Q2: 哈希查找的特点?
+
+**答案:**
+- 平均时间复杂度 O(1)
+- 需要额外空间
+- 可能哈希冲突
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/栈与队列.md b/docs/android面试/算法与数据结构/栈与队列.md
new file mode 100644
index 0000000..d1a6ba0
--- /dev/null
+++ b/docs/android面试/算法与数据结构/栈与队列.md
@@ -0,0 +1,169 @@
+# 栈与队列
+
+## 目录
+- [栈基础](#栈基础)
+- [队列基础](#队列基础)
+- [栈与队列应用](#栈与队列应用)
+- [算法题](#算法题)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 栈基础
+
+### 栈定义
+
+```java
+// 栈:后进先出(LIFO)
+Stack stack = new Stack<>();
+stack.push(1);
+stack.push(2);
+int top = stack.pop(); // 2
+```
+
+### 栈实现
+
+```java
+public class MyStack {
+ private List list = new ArrayList<>();
+
+ public void push(int x) {
+ list.add(x);
+ }
+
+ public int pop() {
+ return list.remove(list.size() - 1);
+ }
+
+ public int peek() {
+ return list.get(list.size() - 1);
+ }
+
+ public boolean empty() {
+ return list.isEmpty();
+ }
+}
+```
+
+---
+
+## 队列基础
+
+### 队列定义
+
+```java
+// 队列:先进先出(FIFO)
+Queue queue = new LinkedList<>();
+queue.offer(1);
+queue.offer(2);
+int front = queue.poll(); // 1
+```
+
+### 队列实现
+
+```java
+public class MyQueue {
+ private List list = new ArrayList<>();
+
+ public void offer(int x) {
+ list.add(x);
+ }
+
+ public int poll() {
+ return list.remove(0);
+ }
+
+ public int peek() {
+ return list.get(0);
+ }
+
+ public boolean empty() {
+ return list.isEmpty();
+ }
+}
+```
+
+---
+
+## 栈与队列应用
+
+### 栈应用
+
+```java
+// 1. 括号匹配
+public boolean isValid(String s) {
+ Stack stack = new Stack<>();
+ for (char c : s.toCharArray()) {
+ if (c == '(' || c == '[' || c == '{') {
+ stack.push(c);
+ } else {
+ if (stack.isEmpty()) return false;
+ char top = stack.pop();
+ if ((c == ')' && top != '(') ||
+ (c == ']' && top != '[') ||
+ (c == '}' && top != '{')) {
+ return false;
+ }
+ }
+ }
+ return stack.isEmpty();
+}
+
+// 2. 表达式求值
+// 3. 函数调用栈
+```
+
+### 队列应用
+
+```java
+// 1. 广度优先搜索(BFS)
+// 2. 任务调度
+// 3. 消息队列
+```
+
+---
+
+## 算法题
+
+### 题1:用栈实现队列
+
+```java
+class MyQueue {
+ private Stack stack1 = new Stack<>();
+ private Stack stack2 = new Stack<>();
+
+ public void push(int x) {
+ stack1.push(x);
+ }
+
+ public int pop() {
+ if (stack2.isEmpty()) {
+ while (!stack1.isEmpty()) {
+ stack2.push(stack1.pop());
+ }
+ }
+ return stack2.pop();
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 栈和队列的区别?
+
+**答案:**
+- **栈**:后进先出(LIFO)
+- **队列**:先进先出(FIFO)
+
+### Q2: 栈的应用?
+
+**答案:**
+- 括号匹配
+- 表达式求值
+- 函数调用栈
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/算法与数据结构/树与二叉树.md b/docs/android面试/算法与数据结构/树与二叉树.md
new file mode 100644
index 0000000..a581915
--- /dev/null
+++ b/docs/android面试/算法与数据结构/树与二叉树.md
@@ -0,0 +1,168 @@
+# 树与二叉树
+
+## 目录
+- [树基础](#树基础)
+- [二叉树基础](#二叉树基础)
+- [二叉树遍历](#二叉树遍历)
+- [常见算法](#常见算法)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 树基础
+
+### 树定义
+
+```java
+// 树:由节点和边组成的非线性数据结构
+public class TreeNode {
+ int val;
+ List children;
+}
+```
+
+### 树术语
+
+```java
+// 1. 节点:树中的元素
+// 2. 根节点:最顶层节点
+// 3. 叶子节点:没有子节点的节点
+// 4. 深度:从根到节点的路径长度
+// 5. 高度:树的最大深度
+```
+
+---
+
+## 二叉树基础
+
+### 二叉树定义
+
+```java
+// 二叉树:每个节点最多有两个子节点
+public class TreeNode {
+ int val;
+ TreeNode left;
+ TreeNode right;
+
+ TreeNode(int val) {
+ this.val = val;
+ }
+}
+```
+
+### 二叉树类型
+
+```java
+// 1. 满二叉树:所有节点都有两个子节点
+// 2. 完全二叉树:除了最后一层,其他层都是满的
+// 3. 二叉搜索树:左子树 < 根 < 右子树
+// 4. 平衡二叉树:左右子树高度差不超过 1
+```
+
+---
+
+## 二叉树遍历
+
+### 前序遍历
+
+```java
+// 根 → 左 → 右
+public void preorder(TreeNode root) {
+ if (root == null) return;
+ System.out.println(root.val);
+ preorder(root.left);
+ preorder(root.right);
+}
+```
+
+### 中序遍历
+
+```java
+// 左 → 根 → 右
+public void inorder(TreeNode root) {
+ if (root == null) return;
+ inorder(root.left);
+ System.out.println(root.val);
+ inorder(root.right);
+}
+```
+
+### 后序遍历
+
+```java
+// 左 → 右 → 根
+public void postorder(TreeNode root) {
+ if (root == null) return;
+ postorder(root.left);
+ postorder(root.right);
+ System.out.println(root.val);
+}
+```
+
+### 层序遍历
+
+```java
+// 按层遍历
+public void levelOrder(TreeNode root) {
+ if (root == null) return;
+ Queue queue = new LinkedList<>();
+ queue.offer(root);
+ while (!queue.isEmpty()) {
+ TreeNode node = queue.poll();
+ System.out.println(node.val);
+ if (node.left != null) queue.offer(node.left);
+ if (node.right != null) queue.offer(node.right);
+ }
+}
+```
+
+---
+
+## 常见算法
+
+### 题1:二叉树的最大深度
+
+```java
+public int maxDepth(TreeNode root) {
+ if (root == null) return 0;
+ return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
+}
+```
+
+### 题2:验证二叉搜索树
+
+```java
+public boolean isValidBST(TreeNode root) {
+ return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
+}
+
+private boolean isValidBST(TreeNode root, long min, long max) {
+ if (root == null) return true;
+ if (root.val <= min || root.val >= max) return false;
+ return isValidBST(root.left, min, root.val) &&
+ isValidBST(root.right, root.val, max);
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 二叉树的遍历方式?
+
+**答案:**
+1. 前序遍历:根 → 左 → 右
+2. 中序遍历:左 → 根 → 右
+3. 后序遍历:左 → 右 → 根
+4. 层序遍历:按层遍历
+
+### Q2: 二叉搜索树的特点?
+
+**答案:**
+- 左子树所有节点 < 根节点
+- 右子树所有节点 > 根节点
+- 中序遍历是有序的
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/AMS原理.md b/docs/android面试/系统原理/AMS原理.md
new file mode 100644
index 0000000..b6d3a3f
--- /dev/null
+++ b/docs/android面试/系统原理/AMS原理.md
@@ -0,0 +1,178 @@
+# AMS原理
+
+## 目录
+- [AMS架构](#ams架构)
+- [Activity启动流程](#activity启动流程)
+- [Service启动流程](#service启动流程)
+- [BroadcastReceiver流程](#broadcastreceiver流程)
+- [AMS源码分析](#ams源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## AMS架构
+
+### AMS 简介
+
+```java
+// AMS:Activity Manager Service
+// 管理 Activity、Service、BroadcastReceiver 等组件
+// 系统服务,运行在 system_server 进程
+```
+
+### AMS 职责
+
+```java
+// 1. Activity 生命周期管理
+// 2. Service 生命周期管理
+// 3. BroadcastReceiver 管理
+// 4. 进程管理
+// 5. 任务栈管理
+```
+
+---
+
+## Activity启动流程
+
+### 启动流程
+
+```
+1. startActivity()
+2. ActivityManagerService.startActivity()
+3. ActivityStackSupervisor.startActivityLocked()
+4. ActivityStack.startActivityLocked()
+5. ActivityStack.resumeTopActivityLocked()
+6. ActivityStackSupervisor.realStartActivityLocked()
+7. ApplicationThread.scheduleLaunchActivity()
+8. ActivityThread.handleLaunchActivity()
+9. Activity.onCreate()
+```
+
+### 关键步骤
+
+```java
+// 1. 检查权限和 Intent
+// 2. 创建 ActivityRecord
+// 3. 检查目标进程是否存在
+// 4. 如果不存在,启动进程
+// 5. 发送启动消息到目标进程
+// 6. 目标进程创建 Activity
+```
+
+---
+
+## Service启动流程
+
+### 启动流程
+
+```
+1. startService()
+2. ActivityManagerService.startService()
+3. ActiveServices.startServiceLocked()
+4. ActiveServices.bringUpServiceLocked()
+5. ApplicationThread.scheduleCreateService()
+6. ActivityThread.handleCreateService()
+7. Service.onCreate()
+```
+
+### 绑定流程
+
+```
+1. bindService()
+2. ActivityManagerService.bindService()
+3. ActiveServices.requestServiceBindingLocked()
+4. ApplicationThread.scheduleBindService()
+5. ActivityThread.handleBindService()
+6. Service.onBind()
+```
+
+---
+
+## BroadcastReceiver流程
+
+### 注册流程
+
+```
+1. registerReceiver()
+2. ActivityManagerService.registerReceiver()
+3. 保存到 ReceiverList
+```
+
+### 发送流程
+
+```
+1. sendBroadcast()
+2. ActivityManagerService.broadcastIntent()
+3. 查找匹配的 Receiver
+4. 发送到目标进程
+5. ApplicationThread.scheduleReceiver()
+6. ActivityThread.handleReceiver()
+7. BroadcastReceiver.onReceive()
+```
+
+---
+
+## AMS源码分析
+
+### 关键类
+
+```java
+// ActivityManagerService:AMS 主类
+// ActivityStack:Activity 栈
+// ActivityStackSupervisor:栈管理器
+// ProcessRecord:进程记录
+// ActivityRecord:Activity 记录
+```
+
+### 关键方法
+
+```java
+// startActivity():启动 Activity
+// startService():启动 Service
+// broadcastIntent():发送广播
+// getRunningAppProcesses():获取运行进程
+```
+
+---
+
+## 面试常见问题
+
+### Q1: AMS 的作用?
+
+**答案:**
+- 管理 Activity、Service、BroadcastReceiver
+- 管理进程和任务栈
+- 系统核心服务
+
+### Q2: Activity 启动流程?
+
+**答案:**
+1. startActivity()
+2. AMS.startActivity()
+3. 检查权限和 Intent
+4. 创建或复用进程
+5. 发送启动消息
+6. ActivityThread 创建 Activity
+
+### Q3: Service 启动流程?
+
+**答案:**
+1. startService()
+2. AMS.startService()
+3. 检查进程是否存在
+4. 启动进程(如需要)
+5. 创建 Service
+6. 调用 onCreate()
+
+### Q4: BroadcastReceiver 流程?
+
+**答案:**
+1. 注册:registerReceiver()
+2. 发送:sendBroadcast()
+3. AMS 查找匹配的 Receiver
+4. 发送到目标进程
+5. 调用 onReceive()
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/Binder机制.md b/docs/android面试/系统原理/Binder机制.md
new file mode 100644
index 0000000..879beb3
--- /dev/null
+++ b/docs/android面试/系统原理/Binder机制.md
@@ -0,0 +1,239 @@
+# Binder机制
+
+## 目录
+- [Binder原理](#binder原理)
+- [Binder架构](#binder架构)
+- [Binder通信流程](#binder通信流程)
+- [AIDL](#aidl)
+- [Binder性能](#binder性能)
+- [Binder源码分析](#binder源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Binder原理
+
+### Binder 简介
+
+```java
+// Binder:Android 的进程间通信(IPC)机制
+// - 基于 Linux 内核的驱动
+// - 高性能
+// - 安全性好
+// - 一次拷贝
+```
+
+### 为什么使用 Binder?
+
+```java
+// 1. 性能:一次拷贝,比 Socket 快
+// 2. 安全:基于 UID/PID 的身份验证
+// 3. 易用:面向对象的接口
+// 4. 稳定:内核驱动,稳定性好
+```
+
+---
+
+## Binder架构
+
+### 架构图
+
+```
+┌─────────────┐
+│ Client │ ←─── 客户端进程
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Proxy │ ←─── 代理对象
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Binder │ ←─── Binder 驱动
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Stub │ ←─── 存根对象
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Service │ ←─── 服务端进程
+└─────────────┘
+```
+
+### 核心组件
+
+```java
+// 1. Binder 驱动:Linux 内核模块
+// 2. ServiceManager:管理所有服务
+// 3. Binder 代理:客户端代理对象
+// 4. Binder 实体:服务端真实对象
+```
+
+---
+
+## Binder通信流程
+
+### 通信流程
+
+```
+1. Client 调用 Proxy 方法
+2. Proxy 将数据打包(Parcel)
+3. 通过 Binder 驱动发送到 Service
+4. Service 的 Stub 接收数据
+5. Stub 解包数据,调用真实方法
+6. 返回结果,反向传输
+```
+
+### 数据传递
+
+```java
+// Binder 使用 Parcel 传递数据
+// Parcel:轻量级序列化机制
+
+Parcel parcel = Parcel.obtain();
+parcel.writeString("Hello");
+parcel.writeInt(123);
+parcel.setDataPosition(0);
+
+String str = parcel.readString();
+int num = parcel.readInt();
+parcel.recycle();
+```
+
+---
+
+## AIDL
+
+### AIDL 定义
+
+```java
+// AIDL:Android Interface Definition Language
+// 用于定义跨进程接口
+
+// IMyService.aidl
+interface IMyService {
+ int add(int a, int b);
+ void setData(String data);
+}
+```
+
+### AIDL 使用
+
+```java
+// 服务端实现
+public class MyService extends Service {
+ private IMyService.Stub binder = new IMyService.Stub() {
+ @Override
+ public int add(int a, int b) {
+ return a + b;
+ }
+
+ @Override
+ public void setData(String data) {
+ // 处理数据
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return binder;
+ }
+}
+
+// 客户端使用
+private ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IMyService myService = IMyService.Stub.asInterface(service);
+ int result = myService.add(1, 2);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+};
+```
+
+---
+
+## Binder性能
+
+### 性能优势
+
+```java
+// 1. 一次拷贝:数据只拷贝一次
+// 2. 内存映射:使用 mmap
+// 3. 内核优化:内核驱动优化
+```
+
+### 性能对比
+
+```java
+// Binder vs 其他 IPC
+// - Socket:两次拷贝,性能差
+// - 管道:两次拷贝,性能差
+// - 共享内存:需要同步,复杂
+// - Binder:一次拷贝,性能好
+```
+
+---
+
+## Binder源码分析
+
+### 关键类
+
+```java
+// IBinder:Binder 接口
+// Binder:Binder 基类
+// BinderProxy:Binder 代理
+// Parcel:数据容器
+```
+
+### 关键流程
+
+```java
+// 1. 服务注册:ServiceManager.addService()
+// 2. 服务获取:ServiceManager.getService()
+// 3. 数据传递:通过 Binder 驱动
+// 4. 方法调用:Proxy → Stub
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Binder 的原理?
+
+**答案:**
+- 基于 Linux 内核的驱动
+- 使用内存映射(mmap)实现一次拷贝
+- 通过 Binder 驱动实现进程间通信
+
+### Q2: 为什么 Android 使用 Binder?
+
+**答案:**
+1. 性能好:一次拷贝
+2. 安全性:基于 UID/PID 验证
+3. 易用性:面向对象接口
+4. 稳定性:内核驱动
+
+### Q3: Binder 通信流程?
+
+**答案:**
+1. Client 调用 Proxy
+2. Proxy 打包数据
+3. 通过 Binder 驱动发送
+4. Service 的 Stub 接收
+5. Stub 调用真实方法
+6. 返回结果
+
+### Q4: AIDL 的作用?
+
+**答案:**
+- 定义跨进程接口
+- 自动生成 Proxy 和 Stub
+- 简化 Binder 使用
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/View绘制流程.md b/docs/android面试/系统原理/View绘制流程.md
new file mode 100644
index 0000000..ce184f4
--- /dev/null
+++ b/docs/android面试/系统原理/View绘制流程.md
@@ -0,0 +1,263 @@
+# View绘制流程
+
+## 目录
+- [View绘制流程](#view绘制流程)
+- [measure过程](#measure过程)
+- [layout过程](#layout过程)
+- [draw过程](#draw过程)
+- [自定义View](#自定义view)
+- [View绘制优化](#view绘制优化)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## View绘制流程
+
+### 绘制流程
+
+```
+1. measure():测量 View 大小
+2. layout():确定 View 位置
+3. draw():绘制 View 内容
+```
+
+### 流程调用
+
+```java
+// ViewRootImpl.performTraversals()
+// 1. performMeasure()
+// 2. performLayout()
+// 3. performDraw()
+```
+
+---
+
+## measure过程
+
+### measure 方法
+
+```java
+// View.measure()
+public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
+ // 1. 调用 onMeasure()
+ onMeasure(widthMeasureSpec, heightMeasureSpec);
+ // 2. 保存测量结果
+}
+
+// View.onMeasure()
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(
+ getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
+ getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)
+ );
+}
+```
+
+### MeasureSpec
+
+```java
+// MeasureSpec:测量规格
+// 包含模式和大小
+
+// 模式:
+// 1. EXACTLY:精确值
+// 2. AT_MOST:最大不超过
+// 3. UNSPECIFIED:未指定
+
+int mode = MeasureSpec.getMode(measureSpec);
+int size = MeasureSpec.getSize(measureSpec);
+```
+
+### ViewGroup measure
+
+```java
+// ViewGroup.onMeasure()
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // 1. 测量所有子 View
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ measureChild(child, widthMeasureSpec, heightMeasureSpec);
+ }
+ // 2. 根据子 View 确定自己的大小
+ setMeasuredDimension(width, height);
+}
+```
+
+---
+
+## layout过程
+
+### layout 方法
+
+```java
+// View.layout()
+public void layout(int l, int t, int r, int b) {
+ // 1. 保存位置
+ setFrame(l, t, r, b);
+ // 2. 调用 onLayout()
+ onLayout(changed, l, t, r, b);
+}
+
+// View.onLayout():空实现
+protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+}
+```
+
+### ViewGroup layout
+
+```java
+// ViewGroup.onLayout()
+protected abstract void onLayout(boolean changed, int l, int t, int r, int b);
+
+// 子类实现,确定子 View 位置
+@Override
+protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ child.layout(left, top, right, bottom);
+ }
+}
+```
+
+---
+
+## draw过程
+
+### draw 方法
+
+```java
+// View.draw()
+public void draw(Canvas canvas) {
+ // 1. 绘制背景
+ drawBackground(canvas);
+ // 2. 保存图层
+ // 3. 绘制内容
+ onDraw(canvas);
+ // 4. 绘制子 View
+ dispatchDraw(canvas);
+ // 5. 绘制装饰(滚动条等)
+ onDrawForeground(canvas);
+}
+```
+
+### onDraw
+
+```java
+// View.onDraw():绘制内容
+protected void onDraw(Canvas canvas) {
+ // 自定义绘制
+ canvas.drawRect(rect, paint);
+ canvas.drawText(text, x, y, paint);
+}
+```
+
+### dispatchDraw
+
+```java
+// ViewGroup.dispatchDraw():绘制子 View
+protected void dispatchDraw(Canvas canvas) {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ drawChild(canvas, child, drawingTime);
+ }
+}
+```
+
+---
+
+## 自定义View
+
+### 自定义 View 步骤
+
+```java
+// 1. 继承 View 或 ViewGroup
+public class CustomView extends View {
+ public CustomView(Context context) {
+ super(context);
+ init();
+ }
+
+ private void init() {
+ // 初始化
+ }
+
+ // 2. 重写 onMeasure()
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int width = measureWidth(widthMeasureSpec);
+ int height = measureHeight(heightMeasureSpec);
+ setMeasuredDimension(width, height);
+ }
+
+ // 3. 重写 onDraw()
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ // 自定义绘制
+ canvas.drawCircle(centerX, centerY, radius, paint);
+ }
+}
+```
+
+---
+
+## View绘制优化
+
+### 优化方法
+
+```java
+// 1. 减少布局层级
+// 使用 ConstraintLayout 替代嵌套布局
+
+// 2. 使用 ViewStub 延迟加载
+
+
+// 3. 避免过度绘制
+// 移除不必要的背景
+
+// 4. 使用硬件加速
+view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+// 5. 优化 onDraw()
+// 避免在 onDraw() 中创建对象
+// 使用缓存
+```
+
+---
+
+## 面试常见问题
+
+### Q1: View 绘制流程?
+
+**答案:**
+1. measure():测量大小
+2. layout():确定位置
+3. draw():绘制内容
+
+### Q2: measure 过程?
+
+**答案:**
+- 从父 View 到子 View 递归测量
+- 使用 MeasureSpec 传递测量规格
+- 子 View 测量后,父 View 确定自己的大小
+
+### Q3: layout 过程?
+
+**答案:**
+- 从父 View 到子 View 递归布局
+- 确定每个 View 的位置
+- 调用 onLayout() 方法
+
+### Q4: draw 过程?
+
+**答案:**
+1. 绘制背景
+2. 绘制内容(onDraw)
+3. 绘制子 View(dispatchDraw)
+4. 绘制装饰
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/WMS原理.md b/docs/android面试/系统原理/WMS原理.md
new file mode 100644
index 0000000..209fd9f
--- /dev/null
+++ b/docs/android面试/系统原理/WMS原理.md
@@ -0,0 +1,140 @@
+# WMS原理
+
+## 目录
+- [WMS架构](#wms架构)
+- [窗口管理](#窗口管理)
+- [窗口类型](#窗口类型)
+- [窗口层级](#窗口层级)
+- [WMS源码分析](#wms源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## WMS架构
+
+### WMS 简介
+
+```java
+// WMS:Window Manager Service
+// 管理所有窗口的显示、层级、动画等
+// 系统服务,运行在 system_server 进程
+```
+
+### WMS 职责
+
+```java
+// 1. 窗口管理
+// 2. 窗口层级管理
+// 3. 窗口动画
+// 4. 输入事件分发
+// 5. 屏幕旋转
+```
+
+---
+
+## 窗口管理
+
+### 窗口创建
+
+```java
+// Activity 创建窗口
+// 1. Activity.attach()
+// 2. PolicyManager.makeNewWindow()
+// 3. Window.setWindowManager()
+// 4. WindowManager.addView()
+```
+
+### 窗口添加
+
+```java
+// WindowManager.addView()
+WindowManager wm = getWindowManager();
+View view = LayoutInflater.from(this).inflate(R.layout.view, null);
+WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+wm.addView(view, params);
+```
+
+---
+
+## 窗口类型
+
+### 窗口类型
+
+```java
+// 1. APPLICATION:应用窗口
+WindowManager.LayoutParams.TYPE_APPLICATION
+
+// 2. SUB_WINDOW:子窗口
+WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
+
+// 3. SYSTEM_WINDOW:系统窗口
+WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
+WindowManager.LayoutParams.TYPE_TOAST
+```
+
+---
+
+## 窗口层级
+
+### 层级管理
+
+```java
+// Z-Order:窗口层级
+// 数字越大,层级越高
+
+// 窗口层级:
+// 1. 系统窗口:最高
+// 2. 应用窗口:中等
+// 3. 子窗口:最低
+```
+
+---
+
+## WMS源码分析
+
+### 关键类
+
+```java
+// WindowManagerService:WMS 主类
+// WindowState:窗口状态
+// WindowToken:窗口令牌
+// DisplayContent:显示内容
+```
+
+### 关键方法
+
+```java
+// addWindow():添加窗口
+// removeWindow():移除窗口
+// relayoutWindow():重新布局窗口
+```
+
+---
+
+## 面试常见问题
+
+### Q1: WMS 的作用?
+
+**答案:**
+- 管理所有窗口
+- 管理窗口层级
+- 处理窗口动画
+- 分发输入事件
+
+### Q2: 窗口类型?
+
+**答案:**
+1. APPLICATION:应用窗口
+2. SUB_WINDOW:子窗口
+3. SYSTEM_WINDOW:系统窗口
+
+### Q3: 窗口层级?
+
+**答案:**
+- 系统窗口:最高
+- 应用窗口:中等
+- 子窗口:最低
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/Zygote进程.md b/docs/android面试/系统原理/Zygote进程.md
new file mode 100644
index 0000000..991ce7a
--- /dev/null
+++ b/docs/android面试/系统原理/Zygote进程.md
@@ -0,0 +1,116 @@
+# Zygote进程
+
+## 目录
+- [Zygote作用](#zygote作用)
+- [Zygote启动流程](#zygote启动流程)
+- [Zygote进程创建](#zygote进程创建)
+- [Zygote源码分析](#zygote源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Zygote作用
+
+### Zygote 简介
+
+```java
+// Zygote:Android 系统的第一个 Java 进程
+// - 预加载类和资源
+// - 孵化应用进程
+// - 共享代码和资源
+```
+
+### Zygote 优势
+
+```java
+// 1. 快速启动:预加载类和资源
+// 2. 内存共享:共享代码和资源
+// 3. 安全性:进程隔离
+```
+
+---
+
+## Zygote启动流程
+
+### 启动流程
+
+```
+1. Init 进程启动
+2. 启动 Zygote 进程
+3. Zygote 预加载类和资源
+4. Zygote 进入循环,等待请求
+5. 收到请求,fork 新进程
+```
+
+---
+
+## Zygote进程创建
+
+### fork 进程
+
+```java
+// Zygote 收到创建进程请求
+// 1. fork() 创建新进程
+// 2. 新进程继承 Zygote 的代码和资源
+// 3. 新进程执行应用代码
+```
+
+### 进程创建流程
+
+```
+1. AMS 请求创建进程
+2. Zygote 收到请求
+3. Zygote.fork() 创建进程
+4. 新进程执行 ActivityThread.main()
+5. 应用进程启动完成
+```
+
+---
+
+## Zygote源码分析
+
+### 关键类
+
+```java
+// ZygoteInit:Zygote 初始化
+// ZygoteServer:Zygote 服务器
+// Zygote:进程创建
+```
+
+### 关键方法
+
+```java
+// main():Zygote 入口
+// forkAndSpecialize():创建应用进程
+// preload():预加载
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Zygote 的作用?
+
+**答案:**
+- 预加载类和资源
+- 孵化应用进程
+- 共享代码和资源
+
+### Q2: Zygote 启动流程?
+
+**答案:**
+1. Init 进程启动 Zygote
+2. Zygote 预加载
+3. Zygote 进入循环
+4. 收到请求,fork 新进程
+
+### Q3: 为什么使用 Zygote?
+
+**答案:**
+1. 快速启动:预加载类和资源
+2. 内存共享:共享代码和资源
+3. 安全性:进程隔离
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/事件分发机制.md b/docs/android面试/系统原理/事件分发机制.md
new file mode 100644
index 0000000..38451ae
--- /dev/null
+++ b/docs/android面试/系统原理/事件分发机制.md
@@ -0,0 +1,209 @@
+# 事件分发机制
+
+## 目录
+- [事件分发流程](#事件分发流程)
+- [onTouchEvent](#ontouchevent)
+- [onInterceptTouchEvent](#onintercepttouchevent)
+- [事件冲突处理](#事件冲突处理)
+- [事件分发源码分析](#事件分发源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 事件分发流程
+
+### 分发流程
+
+```
+Activity → ViewGroup → View
+ ↓ ↓ ↓
+dispatchTouchEvent()
+ ↓ ↓ ↓
+onInterceptTouchEvent() (仅 ViewGroup)
+ ↓ ↓ ↓
+onTouchEvent()
+```
+
+### 关键方法
+
+```java
+// 1. dispatchTouchEvent():分发事件
+// 2. onInterceptTouchEvent():拦截事件(仅 ViewGroup)
+// 3. onTouchEvent():处理事件
+```
+
+---
+
+## onTouchEvent
+
+### onTouchEvent 方法
+
+```java
+// View.onTouchEvent()
+public boolean onTouchEvent(MotionEvent event) {
+ // 1. 处理点击事件
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ performClick();
+ }
+ // 2. 返回 true 表示消费事件
+ return true;
+}
+```
+
+### 返回值
+
+```java
+// true:消费事件,不再向下传递
+// false:不消费事件,继续向下传递
+```
+
+---
+
+## onInterceptTouchEvent
+
+### onInterceptTouchEvent 方法
+
+```java
+// ViewGroup.onInterceptTouchEvent()
+public boolean onInterceptTouchEvent(MotionEvent ev) {
+ // 返回 true:拦截事件,不传递给子 View
+ // 返回 false:不拦截,传递给子 View
+ return false;
+}
+```
+
+### 使用场景
+
+```java
+// 例如:ScrollView 拦截滑动事件
+@Override
+public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_MOVE) {
+ // 判断是否需要拦截
+ if (needIntercept()) {
+ return true; // 拦截,自己处理
+ }
+ }
+ return false; // 不拦截,传递给子 View
+}
+```
+
+---
+
+## 事件冲突处理
+
+### 冲突场景
+
+```java
+// 1. ScrollView 和 ViewPager 滑动冲突
+// 2. ListView 和 Button 点击冲突
+// 3. 嵌套滑动冲突
+```
+
+### 解决方法
+
+#### 方法1:外部拦截
+
+```java
+// 在父 View 的 onInterceptTouchEvent() 中处理
+@Override
+public boolean onInterceptTouchEvent(MotionEvent ev) {
+ boolean intercepted = false;
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ intercepted = false; // 不拦截 DOWN
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (needIntercept()) {
+ intercepted = true; // 拦截 MOVE
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ intercepted = false; // 不拦截 UP
+ break;
+ }
+ return intercepted;
+}
+```
+
+#### 方法2:内部拦截
+
+```java
+// 在子 View 的 dispatchTouchEvent() 中处理
+@Override
+public boolean dispatchTouchEvent(MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ getParent().requestDisallowInterceptTouchEvent(true);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (needParentHandle()) {
+ getParent().requestDisallowInterceptTouchEvent(false);
+ }
+ break;
+ }
+ return super.dispatchTouchEvent(event);
+}
+```
+
+---
+
+## 事件分发源码分析
+
+### dispatchTouchEvent
+
+```java
+// ViewGroup.dispatchTouchEvent()
+public boolean dispatchTouchEvent(MotionEvent ev) {
+ // 1. 检查是否拦截
+ boolean intercepted = onInterceptTouchEvent(ev);
+
+ if (!intercepted) {
+ // 2. 不拦截,分发给子 View
+ for (int i = childCount - 1; i >= 0; i--) {
+ View child = getChildAt(i);
+ if (child.dispatchTouchEvent(ev)) {
+ return true; // 子 View 消费了事件
+ }
+ }
+ }
+
+ // 3. 子 View 不消费,自己处理
+ return onTouchEvent(ev);
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 事件分发流程?
+
+**答案:**
+Activity → ViewGroup → View
+- dispatchTouchEvent():分发事件
+- onInterceptTouchEvent():拦截事件(仅 ViewGroup)
+- onTouchEvent():处理事件
+
+### Q2: onInterceptTouchEvent 的作用?
+
+**答案:**
+- 决定是否拦截事件
+- 返回 true:拦截,不传递给子 View
+- 返回 false:不拦截,传递给子 View
+
+### Q3: 如何解决滑动冲突?
+
+**答案:**
+1. **外部拦截**:在父 View 的 onInterceptTouchEvent() 中处理
+2. **内部拦截**:在子 View 的 dispatchTouchEvent() 中处理
+
+### Q4: 事件分发的返回值?
+
+**答案:**
+- **true**:消费事件,不再传递
+- **false**:不消费事件,继续传递
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/内存管理.md b/docs/android面试/系统原理/内存管理.md
new file mode 100644
index 0000000..77424ad
--- /dev/null
+++ b/docs/android面试/系统原理/内存管理.md
@@ -0,0 +1,196 @@
+# 内存管理
+
+## 目录
+- [Android内存管理](#android内存管理)
+- [内存分配](#内存分配)
+- [垃圾回收](#垃圾回收)
+- [内存泄漏](#内存泄漏)
+- [内存优化](#内存优化)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Android内存管理
+
+### 内存模型
+
+```java
+// Android 内存模型:
+// 1. Java 堆:对象实例
+// 2. Native 堆:Native 代码分配
+// 3. 栈:方法调用、局部变量
+// 4. 方法区:类信息、常量
+```
+
+### 内存限制
+
+```java
+// 不同设备有不同的内存限制
+// 低端设备:16MB、32MB
+// 中端设备:64MB、128MB
+// 高端设备:256MB、512MB+
+
+// 获取内存限制
+ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+int maxMemory = am.getMemoryClass(); // MB
+```
+
+---
+
+## 内存分配
+
+### 堆内存分配
+
+```java
+// Java 对象分配在堆上
+String str = new String("Hello"); // 分配在堆上
+
+// 大对象可能直接分配在老年代
+byte[] largeArray = new byte[10 * 1024 * 1024]; // 10MB
+```
+
+### 栈内存分配
+
+```java
+// 局部变量分配在栈上
+public void method() {
+ int localVar = 10; // 分配在栈上
+ String str = "Hello"; // 引用在栈上,对象在堆上
+}
+```
+
+---
+
+## 垃圾回收
+
+### GC 类型
+
+```java
+// 1. Minor GC:新生代回收
+// 2. Major GC:老年代回收
+// 3. Full GC:整个堆回收
+```
+
+### GC 算法
+
+```java
+// ART 使用多种 GC 算法:
+// 1. 标记-清除
+// 2. 标记-复制
+// 3. 标记-整理
+// 4. 分代收集
+```
+
+### GC 触发时机
+
+```java
+// 1. 堆内存不足
+// 2. 手动调用 System.gc()
+// 3. 对象分配失败
+```
+
+---
+
+## 内存泄漏
+
+### 常见泄漏场景
+
+```java
+// 1. 静态变量持有 Context
+private static Context sContext; // ❌
+
+// 2. Handler 内存泄漏
+private Handler handler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // Handler 持有 Activity 引用
+ }
+}; // ❌
+
+// 3. 监听器未注销
+sensorManager.registerListener(this, sensor, ...);
+// 忘记注销 // ❌
+
+// 4. 内部类持有外部类引用
+public class Outer {
+ class Inner {
+ // Inner 持有 Outer 引用
+ }
+}
+```
+
+### 检测工具
+
+```java
+// 1. LeakCanary:自动检测内存泄漏
+dependencies {
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
+}
+
+// 2. Memory Profiler:Android Studio 工具
+// 3. MAT:Memory Analyzer Tool
+```
+
+---
+
+## 内存优化
+
+### 优化方法
+
+```java
+// 1. 避免内存泄漏
+// - 使用弱引用
+// - 及时释放资源
+// - 使用 Application Context
+
+// 2. 图片优化
+// - 压缩图片
+// - 使用合适格式
+// - 及时回收 Bitmap
+
+// 3. 对象池
+// - 复用对象
+// - 减少创建开销
+
+// 4. 数据结构优化
+// - 使用合适的数据结构
+// - 避免不必要的对象创建
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Android 内存管理机制?
+
+**答案:**
+- 使用 ART 运行时
+- 分代垃圾回收
+- 自动内存管理
+
+### Q2: 内存泄漏的常见场景?
+
+**答案:**
+1. 静态变量持有 Context
+2. Handler 内存泄漏
+3. 监听器未注销
+4. 内部类持有外部类引用
+
+### Q3: 如何检测内存泄漏?
+
+**答案:**
+1. LeakCanary
+2. Memory Profiler
+3. MAT
+
+### Q4: 如何优化内存?
+
+**答案:**
+1. 避免内存泄漏
+2. 图片优化
+3. 对象池
+4. 数据结构优化
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/系统启动流程.md b/docs/android面试/系统原理/系统启动流程.md
new file mode 100644
index 0000000..6faaac5
--- /dev/null
+++ b/docs/android面试/系统原理/系统启动流程.md
@@ -0,0 +1,147 @@
+# 系统启动流程
+
+## 目录
+- [系统启动流程](#系统启动流程)
+- [BootLoader](#bootloader)
+- [Kernel启动](#kernel启动)
+- [Init进程](#init进程)
+- [Zygote进程](#zygote进程)
+- [SystemServer](#systemserver)
+- [Launcher启动](#launcher启动)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 系统启动流程
+
+### 完整流程
+
+```
+1. BootLoader:引导加载程序
+2. Kernel:Linux 内核启动
+3. Init 进程:第一个用户进程
+4. Zygote 进程:Java 进程孵化器
+5. SystemServer:系统服务
+6. Launcher:桌面启动
+```
+
+---
+
+## BootLoader
+
+### BootLoader 作用
+
+```java
+// BootLoader:引导加载程序
+// - 初始化硬件
+// - 加载内核
+// - 启动内核
+```
+
+---
+
+## Kernel启动
+
+### Kernel 启动
+
+```java
+// Linux 内核启动
+// 1. 初始化硬件
+// 2. 加载驱动
+// 3. 启动 Init 进程
+```
+
+---
+
+## Init进程
+
+### Init 进程
+
+```java
+// Init 进程:第一个用户进程
+// - PID = 1
+// - 启动其他进程
+// - 管理进程生命周期
+```
+
+### Init 启动的服务
+
+```java
+// 1. Zygote
+// 2. ServiceManager
+// 3. 其他系统服务
+```
+
+---
+
+## Zygote进程
+
+### Zygote 启动
+
+```java
+// Zygote 进程启动
+// 1. 预加载类和资源
+// 2. 进入循环,等待请求
+// 3. 收到请求,fork 新进程
+```
+
+---
+
+## SystemServer
+
+### SystemServer 启动
+
+```java
+// SystemServer:系统服务进程
+// 1. Zygote fork SystemServer
+// 2. SystemServer 启动系统服务
+// - ActivityManagerService
+// - WindowManagerService
+// - PackageManagerService
+// - 等其他服务
+```
+
+---
+
+## Launcher启动
+
+### Launcher 启动
+
+```java
+// Launcher:桌面应用
+// 1. SystemServer 启动完成后
+// 2. AMS 启动 Launcher
+// 3. 用户看到桌面
+```
+
+---
+
+## 面试常见问题
+
+### Q1: Android 系统启动流程?
+
+**答案:**
+1. BootLoader
+2. Kernel
+3. Init 进程
+4. Zygote 进程
+5. SystemServer
+6. Launcher
+
+### Q2: Zygote 的作用?
+
+**答案:**
+- 预加载类和资源
+- 孵化应用进程
+- 共享代码和资源
+
+### Q3: SystemServer 的作用?
+
+**答案:**
+- 启动系统服务
+- AMS、WMS、PMS 等
+- 管理系统服务
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统原理/进程与线程.md b/docs/android面试/系统原理/进程与线程.md
new file mode 100644
index 0000000..28ba75a
--- /dev/null
+++ b/docs/android面试/系统原理/进程与线程.md
@@ -0,0 +1,203 @@
+# 进程与线程
+
+## 目录
+- [进程概念](#进程概念)
+- [线程概念](#线程概念)
+- [进程间通信](#进程间通信)
+- [线程间通信](#线程间通信)
+- [进程优先级](#进程优先级)
+- [进程保活](#进程保活)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 进程概念
+
+### 进程定义
+
+```java
+// 进程:程序执行的基本单位
+// - 有独立的内存空间
+// - 进程间相互独立
+// - 进程间通信复杂
+```
+
+### Android 进程
+
+```java
+// Android 进程类型:
+// 1. 前台进程(Foreground)
+// 2. 可见进程(Visible)
+// 3. 服务进程(Service)
+// 4. 后台进程(Background)
+// 5. 空进程(Empty)
+```
+
+---
+
+## 线程概念
+
+### 线程定义
+
+```java
+// 线程:CPU 调度的基本单位
+// - 共享进程的内存空间
+// - 线程间通信简单
+// - 线程切换开销小
+```
+
+### Android 线程
+
+```java
+// Android 线程:
+// 1. 主线程(UI 线程)
+// 2. 工作线程(后台线程)
+```
+
+---
+
+## 进程间通信
+
+### IPC 方式
+
+```java
+// 1. Binder:Android 主要 IPC 方式
+// 2. AIDL:基于 Binder
+// 3. Messenger:基于 Binder
+// 4. ContentProvider:基于 Binder
+// 5. Socket:网络通信
+// 6. 文件共享:简单但不安全
+```
+
+### Binder IPC
+
+```java
+// Binder:Android 主要 IPC 机制
+// - 高性能
+// - 安全性好
+// - 一次拷贝
+```
+
+---
+
+## 线程间通信
+
+### 通信方式
+
+```java
+// 1. Handler:主线程和子线程通信
+Handler handler = new Handler(Looper.getMainLooper());
+handler.post(() -> {
+ // 主线程执行
+});
+
+// 2. AsyncTask:已废弃
+// 3. 协程:Kotlin 推荐
+lifecycleScope.launch {
+ val result = withContext(Dispatchers.IO) {
+ // 后台执行
+ }
+ // 主线程更新 UI
+}
+
+// 4. 共享变量:需要同步
+private volatile boolean flag = false;
+```
+
+---
+
+## 进程优先级
+
+### 优先级类型
+
+```java
+// 1. FOREGROUND_SERVICE:前台服务
+// 2. VISIBLE:可见进程
+// 3. SERVICE:服务进程
+// 4. BACKGROUND:后台进程
+// 5. EMPTY:空进程
+```
+
+### 进程回收
+
+```java
+// 系统按优先级回收进程
+// 优先级低的进程先被回收
+// 释放内存给优先级高的进程
+```
+
+---
+
+## 进程保活
+
+### 保活方式
+
+```java
+// 1. 前台服务
+startForeground(1, notification);
+
+// 2. 双进程守护
+// 两个进程互相守护
+
+// 3. JobScheduler
+JobInfo jobInfo = new JobInfo.Builder(1, componentName)
+ .setPeriodic(15 * 60 * 1000)
+ .build();
+
+// 4. WorkManager
+WorkRequest workRequest = new PeriodicWorkRequest.Builder(
+ MyWorker.class, 15, TimeUnit.MINUTES).build();
+WorkManager.getInstance(context).enqueue(workRequest);
+```
+
+### 注意事项
+
+```java
+// ❌ 不推荐:过度保活
+// 1. 影响用户体验
+// 2. 消耗电量
+// 3. 可能被系统杀死
+
+// ✅ 推荐:合理使用
+// 1. 使用前台服务(重要任务)
+// 2. 使用 JobScheduler(定时任务)
+// 3. 使用 WorkManager(后台任务)
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 进程和线程的区别?
+
+**答案:**
+- **进程**:程序执行的基本单位,有独立内存空间
+- **线程**:CPU 调度的基本单位,共享进程内存空间
+
+### Q2: Android 进程间通信方式?
+
+**答案:**
+1. Binder(主要方式)
+2. AIDL
+3. Messenger
+4. ContentProvider
+5. Socket
+
+### Q3: 线程间通信方式?
+
+**答案:**
+1. Handler
+2. 协程
+3. 共享变量(需要同步)
+
+### Q4: 进程保活方式?
+
+**答案:**
+1. 前台服务
+2. 双进程守护
+3. JobScheduler
+4. WorkManager
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统架构/Clean_Architecture.md b/docs/android面试/系统架构/Clean_Architecture.md
new file mode 100644
index 0000000..2542b24
--- /dev/null
+++ b/docs/android面试/系统架构/Clean_Architecture.md
@@ -0,0 +1,670 @@
+# Clean Architecture
+
+## 目录
+- [Clean Architecture概念](#clean-architecture概念)
+- [分层架构](#分层架构)
+- [依赖规则](#依赖规则)
+- [领域层](#领域层)
+- [数据层](#数据层)
+- [表现层](#表现层)
+- [Clean Architecture实现](#clean-architecture实现)
+- [Clean Architecture最佳实践](#clean-architecture最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Clean Architecture概念
+
+### 什么是 Clean Architecture?
+
+Clean Architecture(整洁架构)是由 Robert C. Martin 提出的一种软件架构设计理念,强调:
+
+1. **独立性**:框架、UI、数据库、外部服务都是可替换的
+2. **可测试性**:业务逻辑可以独立测试
+3. **独立性**:业务逻辑不依赖外部框架
+4. **可维护性**:代码结构清晰,易于维护
+
+### Clean Architecture 架构图
+
+```
+┌─────────────────────────────────────┐
+│ Presentation Layer │ ← 表现层(UI、ViewModel)
+│ (Activities, Fragments, ViewModels) │
+└──────────────┬──────────────────────┘
+ │
+┌──────────────▼──────────────────────┐
+│ Domain Layer │ ← 领域层(业务逻辑)
+│ (Use Cases, Entities, Interfaces) │
+└──────────────┬──────────────────────┘
+ │
+┌──────────────▼──────────────────────┐
+│ Data Layer │ ← 数据层(Repository 实现)
+│ (Repositories, Data Sources, API) │
+└─────────────────────────────────────┘
+```
+
+### Clean Architecture 核心原则
+
+1. **依赖倒置**:依赖方向由外向内
+2. **单一职责**:每个类只有一个职责
+3. **开闭原则**:对扩展开放,对修改关闭
+4. **接口隔离**:使用接口隔离依赖
+
+---
+
+## 分层架构
+
+### 三层架构
+
+#### 1. 表现层(Presentation Layer)
+
+**职责:**
+- 显示 UI
+- 处理用户输入
+- 调用 Use Case
+
+**组件:**
+- Activities
+- Fragments
+- ViewModels
+- Adapters
+
+#### 2. 领域层(Domain Layer)
+
+**职责:**
+- 业务逻辑
+- 业务规则
+- 实体定义
+
+**组件:**
+- Entities(实体)
+- Use Cases(用例)
+- Repository Interfaces(仓库接口)
+
+#### 3. 数据层(Data Layer)
+
+**职责:**
+- 数据获取
+- 数据存储
+- Repository 实现
+
+**组件:**
+- Repository Implementations
+- Data Sources(API、Database、Cache)
+- Data Models
+
+### 依赖方向
+
+```
+表现层 → 领域层 → 数据层
+```
+
+- 表现层依赖领域层
+- 领域层不依赖表现层和数据层
+- 数据层实现领域层的接口
+
+---
+
+## 依赖规则
+
+### 依赖倒置原则
+
+```java
+// ✅ 正确:领域层定义接口,数据层实现接口
+// Domain Layer
+public interface UserRepository {
+ Single> getUsers();
+}
+
+// Data Layer
+public class UserRepositoryImpl implements UserRepository {
+ @Override
+ public Single> getUsers() {
+ // 实现
+ }
+}
+
+// ❌ 错误:领域层依赖数据层
+// Domain Layer
+public class UserUseCase {
+ private UserRepositoryImpl repository; // 依赖具体实现
+}
+```
+
+### 依赖方向
+
+```
+┌─────────────┐
+│ Presentation │
+└──────┬───────┘
+ │ 依赖
+ ↓
+┌─────────────┐
+│ Domain │ ← 核心层,不依赖其他层
+└──────┬───────┘
+ │ 接口
+ ↑ 实现
+┌─────────────┐
+│ Data │
+└─────────────┘
+```
+
+---
+
+## 领域层
+
+### Entity(实体)
+
+```java
+// Domain Layer: Entity
+public class User {
+ private String id;
+ private String name;
+ private String email;
+
+ public User(String id, String name, String email) {
+ this.id = id;
+ this.name = name;
+ this.email = email;
+ }
+
+ // Getters
+ public String getId() { return id; }
+ public String getName() { return name; }
+ public String getEmail() { return email; }
+
+ // 业务逻辑
+ public boolean isValid() {
+ return name != null && !name.isEmpty()
+ && email != null && email.contains("@");
+ }
+}
+```
+
+### Use Case(用例)
+
+```java
+// Domain Layer: Use Case
+public class GetUsersUseCase {
+ private UserRepository repository;
+
+ public GetUsersUseCase(UserRepository repository) {
+ this.repository = repository;
+ }
+
+ public Single> execute() {
+ return repository.getUsers()
+ .map(users -> {
+ // 业务逻辑处理
+ return users.stream()
+ .filter(User::isValid)
+ .collect(Collectors.toList());
+ });
+ }
+}
+
+public class AddUserUseCase {
+ private UserRepository repository;
+
+ public AddUserUseCase(UserRepository repository) {
+ this.repository = repository;
+ }
+
+ public Completable execute(User user) {
+ if (!user.isValid()) {
+ return Completable.error(new IllegalArgumentException("Invalid user"));
+ }
+ return repository.addUser(user);
+ }
+}
+```
+
+### Repository Interface(仓库接口)
+
+```java
+// Domain Layer: Repository Interface
+public interface UserRepository {
+ Single> getUsers();
+ Single getUserById(String id);
+ Completable addUser(User user);
+ Completable updateUser(User user);
+ Completable deleteUser(String id);
+}
+```
+
+---
+
+## 数据层
+
+### Repository Implementation(仓库实现)
+
+```java
+// Data Layer: Repository Implementation
+public class UserRepositoryImpl implements UserRepository {
+ private UserRemoteDataSource remoteDataSource;
+ private UserLocalDataSource localDataSource;
+
+ public UserRepositoryImpl(
+ UserRemoteDataSource remoteDataSource,
+ UserLocalDataSource localDataSource
+ ) {
+ this.remoteDataSource = remoteDataSource;
+ this.localDataSource = localDataSource;
+ }
+
+ @Override
+ public Single> getUsers() {
+ return remoteDataSource.getUsers()
+ .doOnSuccess(localDataSource::saveUsers)
+ .onErrorResumeNext(localDataSource.getUsers());
+ }
+
+ @Override
+ public Single getUserById(String id) {
+ return localDataSource.getUserById(id)
+ .onErrorResumeNext(remoteDataSource.getUserById(id));
+ }
+
+ @Override
+ public Completable addUser(User user) {
+ return remoteDataSource.addUser(user)
+ .andThen(localDataSource.saveUser(user));
+ }
+
+ @Override
+ public Completable updateUser(User user) {
+ return remoteDataSource.updateUser(user)
+ .andThen(localDataSource.updateUser(user));
+ }
+
+ @Override
+ public Completable deleteUser(String id) {
+ return remoteDataSource.deleteUser(id)
+ .andThen(localDataSource.deleteUser(id));
+ }
+}
+```
+
+### Data Source(数据源)
+
+```java
+// Data Layer: Remote Data Source
+public class UserRemoteDataSource {
+ private ApiService apiService;
+
+ public UserRemoteDataSource(ApiService apiService) {
+ this.apiService = apiService;
+ }
+
+ public Single> getUsers() {
+ return apiService.getUsers()
+ .map(userResponses -> {
+ return userResponses.stream()
+ .map(this::mapToUser)
+ .collect(Collectors.toList());
+ });
+ }
+
+ private User mapToUser(UserResponse response) {
+ return new User(
+ response.getId(),
+ response.getName(),
+ response.getEmail()
+ );
+ }
+}
+
+// Data Layer: Local Data Source
+public class UserLocalDataSource {
+ private UserDao userDao;
+
+ public UserLocalDataSource(UserDao userDao) {
+ this.userDao = userDao;
+ }
+
+ public Single> getUsers() {
+ return userDao.getUsers()
+ .map(userEntities -> {
+ return userEntities.stream()
+ .map(this::mapToUser)
+ .collect(Collectors.toList());
+ });
+ }
+
+ public void saveUsers(List users) {
+ List entities = users.stream()
+ .map(this::mapToEntity)
+ .collect(Collectors.toList());
+ userDao.insertUsers(entities);
+ }
+
+ private User mapToUser(UserEntity entity) {
+ return new User(
+ entity.getId(),
+ entity.getName(),
+ entity.getEmail()
+ );
+ }
+
+ private UserEntity mapToEntity(User user) {
+ UserEntity entity = new UserEntity();
+ entity.setId(user.getId());
+ entity.setName(user.getName());
+ entity.setEmail(user.getEmail());
+ return entity;
+ }
+}
+```
+
+---
+
+## 表现层
+
+### ViewModel
+
+```java
+// Presentation Layer: ViewModel
+public class UserViewModel extends ViewModel {
+ private GetUsersUseCase getUsersUseCase;
+ private AddUserUseCase addUserUseCase;
+ private MutableLiveData> users = new MutableLiveData<>();
+ private MutableLiveData error = new MutableLiveData<>();
+ private MutableLiveData loading = new MutableLiveData<>();
+
+ public UserViewModel(
+ GetUsersUseCase getUsersUseCase,
+ AddUserUseCase addUserUseCase
+ ) {
+ this.getUsersUseCase = getUsersUseCase;
+ this.addUserUseCase = addUserUseCase;
+ }
+
+ public LiveData> getUsers() {
+ return users;
+ }
+
+ public LiveData getError() {
+ return error;
+ }
+
+ public LiveData getLoading() {
+ return loading;
+ }
+
+ public void loadUsers() {
+ loading.setValue(true);
+ getUsersUseCase.execute()
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ userList -> {
+ loading.setValue(false);
+ users.setValue(userList);
+ },
+ throwable -> {
+ loading.setValue(false);
+ error.setValue(throwable.getMessage());
+ }
+ );
+ }
+
+ public void addUser(String name, String email) {
+ loading.setValue(true);
+ User user = new User(UUID.randomUUID().toString(), name, email);
+ addUserUseCase.execute(user)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> {
+ loading.setValue(false);
+ loadUsers();
+ },
+ throwable -> {
+ loading.setValue(false);
+ error.setValue(throwable.getMessage());
+ }
+ );
+ }
+}
+```
+
+### Activity/Fragment
+
+```java
+// Presentation Layer: Activity
+public class UserActivity extends AppCompatActivity {
+ private UserViewModel viewModel;
+ private ActivityUserBinding binding;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_user);
+
+ // 依赖注入
+ UserRepository repository = new UserRepositoryImpl(
+ new UserRemoteDataSource(createApiService()),
+ new UserLocalDataSource(createUserDao())
+ );
+
+ GetUsersUseCase getUsersUseCase = new GetUsersUseCase(repository);
+ AddUserUseCase addUserUseCase = new AddUserUseCase(repository);
+
+ viewModel = ViewModelProviders.of(this, new ViewModelFactory(
+ getUsersUseCase,
+ addUserUseCase
+ )).get(UserViewModel.class);
+
+ binding.setViewModel(viewModel);
+ binding.setLifecycleOwner(this);
+
+ observeViewModel();
+ }
+
+ private void observeViewModel() {
+ viewModel.getUsers().observe(this, users -> {
+ adapter.updateUsers(users);
+ });
+
+ viewModel.getError().observe(this, error -> {
+ Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+ });
+ }
+}
+```
+
+---
+
+## Clean Architecture实现
+
+### 项目结构
+
+```
+app/
+├── presentation/ # 表现层
+│ ├── ui/
+│ │ ├── activities/
+│ │ ├── fragments/
+│ │ └── adapters/
+│ └── viewmodels/
+├── domain/ # 领域层
+│ ├── entities/
+│ ├── usecases/
+│ └── repositories/
+└── data/ # 数据层
+ ├── repositories/
+ ├── datasources/
+ │ ├── remote/
+ │ └── local/
+ └── models/
+```
+
+### 依赖配置
+
+```gradle
+// app/build.gradle
+dependencies {
+ // 表现层依赖领域层
+ implementation project(':domain')
+
+ // 表现层依赖数据层(用于依赖注入)
+ implementation project(':data')
+}
+
+// domain/build.gradle
+dependencies {
+ // 领域层不依赖其他层,只依赖 RxJava 等工具库
+ implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
+}
+
+// data/build.gradle
+dependencies {
+ // 数据层依赖领域层(实现接口)
+ implementation project(':domain')
+
+ // 数据层依赖第三方库
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+ implementation 'androidx.room:room-runtime:2.3.0'
+}
+```
+
+---
+
+## Clean Architecture最佳实践
+
+### 1. 依赖倒置
+
+```java
+// ✅ 正确:领域层定义接口
+// Domain Layer
+public interface UserRepository {
+ Single> getUsers();
+}
+
+// Data Layer 实现接口
+public class UserRepositoryImpl implements UserRepository {
+ // 实现
+}
+
+// ❌ 错误:领域层依赖数据层
+// Domain Layer
+public class UserUseCase {
+ private UserRepositoryImpl repository; // 依赖具体实现
+}
+```
+
+### 2. 单一职责
+
+```java
+// ✅ 正确:每个类只有一个职责
+public class GetUsersUseCase {
+ public Single> execute() {
+ // 只负责获取用户列表
+ }
+}
+
+public class AddUserUseCase {
+ public Completable execute(User user) {
+ // 只负责添加用户
+ }
+}
+
+// ❌ 错误:一个类承担多个职责
+public class UserUseCase {
+ public void getUsers() { }
+ public void addUser() { }
+ public void updateUser() { }
+ public void deleteUser() { }
+}
+```
+
+### 3. 接口隔离
+
+```java
+// ✅ 正确:接口职责单一
+public interface UserRepository {
+ Single> getUsers();
+ Single getUserById(String id);
+}
+
+// ❌ 错误:接口职责过多
+public interface UserRepository {
+ void getUsers();
+ void addUser();
+ void updateUser();
+ void deleteUser();
+ void uploadFile();
+ void downloadFile();
+}
+```
+
+### 4. 测试
+
+```java
+// 领域层可以独立测试
+public class GetUsersUseCaseTest {
+ @Test
+ public void testExecute() {
+ UserRepository mockRepository = mock(UserRepository.class);
+ when(mockRepository.getUsers()).thenReturn(Single.just(users));
+
+ GetUsersUseCase useCase = new GetUsersUseCase(mockRepository);
+ useCase.execute()
+ .test()
+ .assertValue(users);
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是 Clean Architecture?
+
+**答案:**
+Clean Architecture(整洁架构)是由 Robert C. Martin 提出的一种软件架构设计理念,强调:
+1. 独立性:框架、UI、数据库都是可替换的
+2. 可测试性:业务逻辑可以独立测试
+3. 独立性:业务逻辑不依赖外部框架
+4. 可维护性:代码结构清晰,易于维护
+
+### Q2: Clean Architecture 的分层?
+
+**答案:**
+1. **表现层**:UI、ViewModel、Activities、Fragments
+2. **领域层**:Entities、Use Cases、Repository Interfaces
+3. **数据层**:Repository Implementations、Data Sources
+
+### Q3: Clean Architecture 的依赖规则?
+
+**答案:**
+1. **依赖倒置**:领域层定义接口,数据层实现接口
+2. **依赖方向**:表现层 → 领域层 → 数据层
+3. **领域层独立**:领域层不依赖其他层
+
+### Q4: Use Case 的作用?
+
+**答案:**
+Use Case(用例)封装了特定的业务逻辑,每个 Use Case 只负责一个业务功能,使业务逻辑清晰、可测试、可复用。
+
+### Q5: Repository 模式的作用?
+
+**答案:**
+Repository 模式封装了数据访问逻辑,提供统一的数据访问接口,隐藏了数据来源(网络、数据库、缓存)的细节。
+
+### Q6: Clean Architecture 的优势?
+
+**答案:**
+1. 可测试性:业务逻辑可以独立测试
+2. 可维护性:代码结构清晰
+3. 可扩展性:易于添加新功能
+4. 独立性:不依赖外部框架
+
+---
+
+## 总结
+
+Clean Architecture 是一种优秀的软件架构设计理念,通过分层架构和依赖倒置,实现了业务逻辑的独立性和可测试性。在实际项目中,需要合理划分层次、定义接口、实现依赖倒置。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统架构/MVC架构.md b/docs/android面试/系统架构/MVC架构.md
new file mode 100644
index 0000000..26f5bc8
--- /dev/null
+++ b/docs/android面试/系统架构/MVC架构.md
@@ -0,0 +1,428 @@
+# MVC架构
+
+## 目录
+- [MVC模式介绍](#mvc模式介绍)
+- [Android中的MVC](#android中的mvc)
+- [MVC优缺点](#mvc优缺点)
+- [MVC实现示例](#mvc实现示例)
+- [MVC适用场景](#mvc适用场景)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## MVC模式介绍
+
+### MVC 概念
+
+MVC(Model-View-Controller)是一种软件架构模式,将应用程序分为三个核心组件:
+
+- **Model(模型)**:数据和业务逻辑
+- **View(视图)**:用户界面
+- **Controller(控制器)**:处理用户输入,协调 Model 和 View
+
+### MVC 架构图
+
+```
+┌─────────┐
+│ View │ ←─── 显示数据
+└────┬────┘
+ │ 用户交互
+ ↓
+┌─────────┐
+│Controller│ ←─── 处理输入,更新 Model
+└────┬────┘
+ │ 更新
+ ↓
+┌─────────┐
+│ Model │ ←─── 数据和业务逻辑
+└─────────┘
+```
+
+### MVC 数据流
+
+1. **用户操作 View** → Controller 接收输入
+2. **Controller 处理** → 更新 Model
+3. **Model 变化** → 通知 View 更新
+4. **View 更新** → 显示最新数据
+
+---
+
+## Android中的MVC
+
+### Android MVC 结构
+
+在 Android 中,MVC 模式的实现:
+
+- **Model**:数据模型、业务逻辑、数据访问层
+- **View**:XML 布局文件、自定义 View
+- **Controller**:Activity、Fragment
+
+### Android MVC 示例
+
+```java
+// Model:数据模型
+public class User {
+ private String name;
+ private String email;
+
+ public User(String name, String email) {
+ this.name = name;
+ this.email = email;
+ }
+
+ // Getters and Setters
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+
+ public String getEmail() { return email; }
+ public void setEmail(String email) { this.email = email; }
+}
+
+// Model:业务逻辑
+public class UserModel {
+ private List users = new ArrayList<>();
+
+ public void addUser(User user) {
+ users.add(user);
+ }
+
+ public List getUsers() {
+ return users;
+ }
+
+ public User getUser(int position) {
+ return users.get(position);
+ }
+}
+
+// View:XML 布局
+// activity_main.xml
+
+
+
+
+
+
+
+// Controller:Activity
+public class MainActivity extends AppCompatActivity {
+ private EditText etName, etEmail;
+ private Button btnAdd;
+ private ListView lvUsers;
+ private UserModel userModel;
+ private ArrayAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // 初始化 View
+ initViews();
+
+ // 初始化 Model
+ userModel = new UserModel();
+
+ // 初始化 Adapter
+ adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, userModel.getUsers());
+ lvUsers.setAdapter(adapter);
+
+ // 处理用户输入
+ btnAdd.setOnClickListener(v -> {
+ String name = etName.getText().toString();
+ String email = etEmail.getText().toString();
+
+ // Controller 更新 Model
+ User user = new User(name, email);
+ userModel.addUser(user);
+
+ // Controller 更新 View
+ adapter.notifyDataSetChanged();
+ etName.setText("");
+ etEmail.setText("");
+ });
+ }
+
+ private void initViews() {
+ etName = findViewById(R.id.etName);
+ etEmail = findViewById(R.id.etEmail);
+ btnAdd = findViewById(R.id.btnAdd);
+ lvUsers = findViewById(R.id.lvUsers);
+ }
+}
+```
+
+---
+
+## MVC优缺点
+
+### 优点
+
+1. **结构清晰**:职责分离,易于理解
+2. **代码复用**:Model 和 View 可以复用
+3. **易于测试**:Model 可以独立测试
+4. **开发效率高**:适合小型项目快速开发
+
+### 缺点
+
+1. **Activity/Fragment 臃肿**:Controller 承担过多职责
+2. **View 和 Model 耦合**:View 直接依赖 Model
+3. **难以测试**:Activity/Fragment 难以进行单元测试
+4. **维护困难**:随着项目增大,Controller 变得复杂
+
+### Android MVC 的问题
+
+```java
+// ❌ 问题:Activity 承担了太多职责
+public class MainActivity extends AppCompatActivity {
+ // 1. 处理用户输入
+ // 2. 更新 Model
+ // 3. 更新 View
+ // 4. 处理生命周期
+ // 5. 处理配置变更
+ // 6. 处理权限
+ // ... 太多职责
+}
+```
+
+---
+
+## MVC实现示例
+
+### 完整示例:用户列表
+
+```java
+// Model:用户数据模型
+public class User {
+ private String id;
+ private String name;
+ private String email;
+
+ public User(String id, String name, String email) {
+ this.id = id;
+ this.name = name;
+ this.email = email;
+ }
+
+ // Getters and Setters
+ public String getId() { return id; }
+ public String getName() { return name; }
+ public String getEmail() { return email; }
+}
+
+// Model:用户业务逻辑
+public class UserRepository {
+ private List users = new ArrayList<>();
+
+ public void addUser(User user) {
+ users.add(user);
+ }
+
+ public void removeUser(String id) {
+ users.removeIf(user -> user.getId().equals(id));
+ }
+
+ public List getAllUsers() {
+ return new ArrayList<>(users);
+ }
+
+ public User getUserById(String id) {
+ return users.stream()
+ .filter(user -> user.getId().equals(id))
+ .findFirst()
+ .orElse(null);
+ }
+}
+
+// View:布局文件
+// activity_user_list.xml
+
+
+
+
+
+
+
+// Controller:Activity
+public class UserListActivity extends AppCompatActivity {
+ private EditText etName, etEmail;
+ private Button btnAdd;
+ private RecyclerView rvUsers;
+ private UserRepository userRepository;
+ private UserAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_user_list);
+
+ initViews();
+ initModel();
+ setupRecyclerView();
+ setupListeners();
+ }
+
+ private void initViews() {
+ etName = findViewById(R.id.etName);
+ etEmail = findViewById(R.id.etEmail);
+ btnAdd = findViewById(R.id.btnAdd);
+ rvUsers = findViewById(R.id.rvUsers);
+ }
+
+ private void initModel() {
+ userRepository = new UserRepository();
+ }
+
+ private void setupRecyclerView() {
+ adapter = new UserAdapter(userRepository.getAllUsers());
+ rvUsers.setLayoutManager(new LinearLayoutManager(this));
+ rvUsers.setAdapter(adapter);
+ }
+
+ private void setupListeners() {
+ btnAdd.setOnClickListener(v -> {
+ String name = etName.getText().toString();
+ String email = etEmail.getText().toString();
+
+ if (!name.isEmpty() && !email.isEmpty()) {
+ // Controller 更新 Model
+ User user = new User(UUID.randomUUID().toString(), name, email);
+ userRepository.addUser(user);
+
+ // Controller 更新 View
+ adapter.updateUsers(userRepository.getAllUsers());
+ etName.setText("");
+ etEmail.setText("");
+ }
+ });
+ }
+}
+
+// View:Adapter
+public class UserAdapter extends RecyclerView.Adapter {
+ private List users;
+
+ public UserAdapter(List users) {
+ this.users = users;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_user, parent, false);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ User user = users.get(position);
+ holder.tvName.setText(user.getName());
+ holder.tvEmail.setText(user.getEmail());
+ }
+
+ @Override
+ public int getItemCount() {
+ return users.size();
+ }
+
+ public void updateUsers(List users) {
+ this.users = users;
+ notifyDataSetChanged();
+ }
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ TextView tvName, tvEmail;
+
+ ViewHolder(View itemView) {
+ super(itemView);
+ tvName = itemView.findViewById(R.id.tvName);
+ tvEmail = itemView.findViewById(R.id.tvEmail);
+ }
+ }
+}
+```
+
+---
+
+## MVC适用场景
+
+### 适合使用 MVC 的场景
+
+1. **小型项目**:功能简单,快速开发
+2. **原型开发**:快速验证想法
+3. **学习项目**:理解架构模式
+4. **简单 UI**:界面简单,交互少
+
+### 不适合使用 MVC 的场景
+
+1. **大型项目**:代码复杂,难以维护
+2. **复杂业务逻辑**:Controller 会变得臃肿
+3. **需要单元测试**:Activity 难以测试
+4. **团队协作**:多人开发容易冲突
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是 MVC 模式?
+
+**答案:**
+MVC(Model-View-Controller)是一种软件架构模式,将应用程序分为三个核心组件:
+- **Model**:数据和业务逻辑
+- **View**:用户界面
+- **Controller**:处理用户输入,协调 Model 和 View
+
+### Q2: Android 中 MVC 的实现?
+
+**答案:**
+- **Model**:数据模型、业务逻辑、数据访问层
+- **View**:XML 布局文件、自定义 View
+- **Controller**:Activity、Fragment
+
+### Q3: MVC 的优缺点?
+
+**答案:**
+- **优点**:结构清晰、代码复用、易于理解
+- **缺点**:Activity 臃肿、View 和 Model 耦合、难以测试、维护困难
+
+### Q4: MVC 和 MVP 的区别?
+
+**答案:**
+- **MVC**:View 可以直接访问 Model,Controller 处理输入和更新
+- **MVP**:View 和 Model 完全解耦,Presenter 作为中间层,View 通过接口与 Presenter 通信
+
+### Q5: 为什么 MVC 在 Android 中不常用?
+
+**答案:**
+1. Activity/Fragment 承担过多职责,变得臃肿
+2. View 和 Model 耦合,难以测试和维护
+3. 随着项目增大,Controller 变得复杂
+4. 不适合大型项目和复杂业务逻辑
+
+### Q6: MVC 适合什么场景?
+
+**答案:**
+- 适合:小型项目、原型开发、学习项目、简单 UI
+- 不适合:大型项目、复杂业务逻辑、需要单元测试、团队协作
+
+---
+
+## 总结
+
+MVC 是一种经典的架构模式,在 Android 中:
+- **Model**:数据和业务逻辑
+- **View**:XML 布局和自定义 View
+- **Controller**:Activity 和 Fragment
+
+虽然 MVC 结构简单,但在 Android 中容易导致 Activity 臃肿、难以测试等问题,因此在实际项目中,更多使用 MVP 或 MVVM 架构。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统架构/MVP架构.md b/docs/android面试/系统架构/MVP架构.md
new file mode 100644
index 0000000..a7581f5
--- /dev/null
+++ b/docs/android面试/系统架构/MVP架构.md
@@ -0,0 +1,644 @@
+# MVP架构
+
+## 目录
+- [MVP模式介绍](#mvp模式介绍)
+- [MVP三层职责](#mvp三层职责)
+- [MVP实现示例](#mvp实现示例)
+- [MVP优缺点](#mvp优缺点)
+- [MVP与MVC对比](#mvp与mvc对比)
+- [MVP最佳实践](#mvp最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## MVP模式介绍
+
+### MVP 概念
+
+MVP(Model-View-Presenter)是一种软件架构模式,是 MVC 的改进版本:
+
+- **Model**:数据和业务逻辑
+- **View**:用户界面(通过接口与 Presenter 通信)
+- **Presenter**:处理业务逻辑,协调 Model 和 View
+
+### MVP 架构图
+
+```
+┌─────────┐
+│ View │ ←─── 显示数据(通过接口)
+└────┬────┘
+ │ 用户交互
+ ↓
+┌─────────┐
+│Presenter │ ←─── 处理业务逻辑
+└────┬────┘
+ │ 更新
+ ↓
+┌─────────┐
+│ Model │ ←─── 数据和业务逻辑
+└─────────┘
+```
+
+### MVP 数据流
+
+1. **用户操作 View** → View 调用 Presenter 方法
+2. **Presenter 处理** → 调用 Model 获取数据
+3. **Model 返回数据** → Presenter 处理数据
+4. **Presenter 更新 View** → 通过接口更新 View
+
+### MVP 核心特点
+
+1. **View 和 Model 完全解耦**:View 不直接访问 Model
+2. **View 通过接口与 Presenter 通信**:便于测试和替换
+3. **Presenter 持有 View 接口引用**:不持有具体 View 实现
+4. **业务逻辑在 Presenter 中**:View 只负责显示
+
+---
+
+## MVP三层职责
+
+### Model 层
+
+**职责:**
+- 数据模型定义
+- 业务逻辑处理
+- 数据访问(网络、数据库、文件等)
+- 数据验证
+
+**特点:**
+- 不依赖 View 和 Presenter
+- 可以独立测试
+- 可以被多个 Presenter 使用
+
+### View 层
+
+**职责:**
+- 显示数据
+- 处理用户输入
+- 提供 UI 反馈(加载、错误提示等)
+
+**特点:**
+- 通过接口与 Presenter 通信
+- 不包含业务逻辑
+- 被动接收 Presenter 的更新
+
+### Presenter 层
+
+**职责:**
+- 处理用户交互
+- 调用 Model 获取数据
+- 处理业务逻辑
+- 更新 View(通过接口)
+
+**特点:**
+- 持有 View 接口引用
+- 不持有具体 View 实现
+- 可以独立测试(使用 Mock View)
+
+---
+
+## MVP实现示例
+
+### 基础 MVP 实现
+
+```java
+// Model:用户数据模型
+public class User {
+ private String id;
+ private String name;
+ private String email;
+
+ public User(String id, String name, String email) {
+ this.id = id;
+ this.name = name;
+ this.email = email;
+ }
+
+ // Getters
+ public String getId() { return id; }
+ public String getName() { return name; }
+ public String getEmail() { return email; }
+}
+
+// Model:用户业务逻辑
+public class UserRepository {
+ private List users = new ArrayList<>();
+
+ public void addUser(User user, Callback callback) {
+ // 模拟网络请求
+ new Thread(() -> {
+ try {
+ Thread.sleep(1000); // 模拟网络延迟
+ users.add(user);
+ callback.onSuccess();
+ } catch (InterruptedException e) {
+ callback.onError(e.getMessage());
+ }
+ }).start();
+ }
+
+ public void getUsers(Callback> callback) {
+ new Thread(() -> {
+ try {
+ Thread.sleep(500);
+ callback.onSuccess(users);
+ } catch (InterruptedException e) {
+ callback.onError(e.getMessage());
+ }
+ }).start();
+ }
+
+ interface Callback {
+ void onSuccess(T data);
+ void onError(String error);
+ }
+}
+
+// View 接口
+public interface UserView {
+ void showLoading();
+ void hideLoading();
+ void showUsers(List users);
+ void showError(String error);
+ void showSuccess(String message);
+ void clearInput();
+}
+
+// Presenter
+public class UserPresenter {
+ private UserView view;
+ private UserRepository repository;
+
+ public UserPresenter(UserView view, UserRepository repository) {
+ this.view = view;
+ this.repository = repository;
+ }
+
+ public void addUser(String name, String email) {
+ if (name.isEmpty() || email.isEmpty()) {
+ view.showError("Name and Email cannot be empty");
+ return;
+ }
+
+ view.showLoading();
+ User user = new User(UUID.randomUUID().toString(), name, email);
+ repository.addUser(user, new UserRepository.Callback() {
+ @Override
+ public void onSuccess(Void data) {
+ view.hideLoading();
+ view.showSuccess("User added successfully");
+ view.clearInput();
+ loadUsers();
+ }
+
+ @Override
+ public void onError(String error) {
+ view.hideLoading();
+ view.showError(error);
+ }
+ });
+ }
+
+ public void loadUsers() {
+ view.showLoading();
+ repository.getUsers(new UserRepository.Callback>() {
+ @Override
+ public void onSuccess(List data) {
+ view.hideLoading();
+ view.showUsers(data);
+ }
+
+ @Override
+ public void onError(String error) {
+ view.hideLoading();
+ view.showError(error);
+ }
+ });
+ }
+
+ public void onDestroy() {
+ view = null; // 防止内存泄漏
+ }
+}
+
+// View 实现:Activity
+public class UserActivity extends AppCompatActivity implements UserView {
+ private EditText etName, etEmail;
+ private Button btnAdd;
+ private RecyclerView rvUsers;
+ private UserPresenter presenter;
+ private UserAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_user);
+
+ initViews();
+ initPresenter();
+ setupRecyclerView();
+ setupListeners();
+
+ presenter.loadUsers();
+ }
+
+ private void initViews() {
+ etName = findViewById(R.id.etName);
+ etEmail = findViewById(R.id.etEmail);
+ btnAdd = findViewById(R.id.btnAdd);
+ rvUsers = findViewById(R.id.rvUsers);
+ }
+
+ private void initPresenter() {
+ UserRepository repository = new UserRepository();
+ presenter = new UserPresenter(this, repository);
+ }
+
+ private void setupRecyclerView() {
+ adapter = new UserAdapter(new ArrayList<>());
+ rvUsers.setLayoutManager(new LinearLayoutManager(this));
+ rvUsers.setAdapter(adapter);
+ }
+
+ private void setupListeners() {
+ btnAdd.setOnClickListener(v -> {
+ String name = etName.getText().toString();
+ String email = etEmail.getText().toString();
+ presenter.addUser(name, email);
+ });
+ }
+
+ // 实现 UserView 接口
+ @Override
+ public void showLoading() {
+ // 显示加载提示
+ }
+
+ @Override
+ public void hideLoading() {
+ // 隐藏加载提示
+ }
+
+ @Override
+ public void showUsers(List users) {
+ adapter.updateUsers(users);
+ }
+
+ @Override
+ public void showError(String error) {
+ Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void showSuccess(String message) {
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void clearInput() {
+ etName.setText("");
+ etEmail.setText("");
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (presenter != null) {
+ presenter.onDestroy();
+ }
+ }
+}
+```
+
+### 使用 RxJava 的 MVP 实现
+
+```java
+// Presenter with RxJava
+public class UserPresenter {
+ private UserView view;
+ private UserRepository repository;
+ private CompositeDisposable disposables = new CompositeDisposable();
+
+ public UserPresenter(UserView view, UserRepository repository) {
+ this.view = view;
+ this.repository = repository;
+ }
+
+ public void addUser(String name, String email) {
+ if (name.isEmpty() || email.isEmpty()) {
+ view.showError("Name and Email cannot be empty");
+ return;
+ }
+
+ view.showLoading();
+ User user = new User(UUID.randomUUID().toString(), name, email);
+
+ Disposable disposable = repository.addUser(user)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> {
+ view.hideLoading();
+ view.showSuccess("User added successfully");
+ view.clearInput();
+ loadUsers();
+ },
+ error -> {
+ view.hideLoading();
+ view.showError(error.getMessage());
+ }
+ );
+
+ disposables.add(disposable);
+ }
+
+ public void loadUsers() {
+ view.showLoading();
+ Disposable disposable = repository.getUsers()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ users -> {
+ view.hideLoading();
+ view.showUsers(users);
+ },
+ error -> {
+ view.hideLoading();
+ view.showError(error.getMessage());
+ }
+ );
+
+ disposables.add(disposable);
+ }
+
+ public void onDestroy() {
+ disposables.clear();
+ view = null;
+ }
+}
+```
+
+---
+
+## MVP优缺点
+
+### 优点
+
+1. **View 和 Model 完全解耦**:View 不直接访问 Model
+2. **易于测试**:Presenter 可以独立测试,使用 Mock View
+3. **代码复用**:Presenter 可以被多个 View 使用
+4. **职责清晰**:每层职责明确
+5. **便于维护**:代码结构清晰,易于维护
+
+### 缺点
+
+1. **代码量增加**:需要定义接口,代码量增加
+2. **接口过多**:每个 View 都需要定义接口
+3. **Presenter 可能臃肿**:复杂业务逻辑可能导致 Presenter 臃肿
+4. **生命周期管理**:需要手动管理 Presenter 的生命周期
+
+---
+
+## MVP与MVC对比
+
+### 主要区别
+
+| 特性 | MVC | MVP |
+|------|-----|-----|
+| View 和 Model | 耦合 | 完全解耦 |
+| View 访问 Model | 可以直接访问 | 不能直接访问 |
+| Controller/Presenter | 处理输入和更新 | 处理业务逻辑 |
+| 测试性 | 难以测试 | 易于测试 |
+| 代码量 | 较少 | 较多 |
+| 适用场景 | 小型项目 | 中大型项目 |
+
+### 代码对比
+
+```java
+// MVC:View 直接访问 Model
+public class MainActivity extends AppCompatActivity {
+ private UserRepository repository;
+
+ private void loadUsers() {
+ repository.getUsers(users -> {
+ // View 直接处理 Model 数据
+ adapter.updateUsers(users);
+ });
+ }
+}
+
+// MVP:View 通过 Presenter 访问 Model
+public class MainActivity extends AppCompatActivity implements UserView {
+ private UserPresenter presenter;
+
+ private void loadUsers() {
+ presenter.loadUsers(); // 通过 Presenter
+ }
+
+ @Override
+ public void showUsers(List users) {
+ // Presenter 通过接口更新 View
+ adapter.updateUsers(users);
+ }
+}
+```
+
+---
+
+## MVP最佳实践
+
+### 1. View 接口设计
+
+```java
+// ✅ 好的接口设计:职责单一
+public interface UserView {
+ void showUsers(List users);
+ void showError(String error);
+ void showLoading();
+ void hideLoading();
+}
+
+// ❌ 不好的接口设计:职责过多
+public interface UserView {
+ void showUsers(List users);
+ void showError(String error);
+ void showLoading();
+ void hideLoading();
+ void navigateToDetail(); // 导航不应该在 View 接口中
+ void requestPermission(); // 权限不应该在 View 接口中
+}
+```
+
+### 2. Presenter 生命周期管理
+
+```java
+public class UserPresenter {
+ private UserView view;
+
+ public void attachView(UserView view) {
+ this.view = view;
+ }
+
+ public void detachView() {
+ this.view = null;
+ }
+
+ public boolean isViewAttached() {
+ return view != null;
+ }
+
+ private void updateView(Runnable update) {
+ if (isViewAttached()) {
+ update.run();
+ }
+ }
+}
+
+// Activity 中使用
+public class UserActivity extends AppCompatActivity implements UserView {
+ private UserPresenter presenter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ presenter = new UserPresenter();
+ presenter.attachView(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ presenter.detachView();
+ }
+}
+```
+
+### 3. 使用 Contract 接口
+
+```java
+// 将 View 和 Presenter 接口放在一起
+public interface UserContract {
+ interface View {
+ void showUsers(List users);
+ void showError(String error);
+ void showLoading();
+ void hideLoading();
+ }
+
+ interface Presenter {
+ void loadUsers();
+ void addUser(String name, String email);
+ void attachView(View view);
+ void detachView();
+ }
+}
+
+// 实现
+public class UserPresenter implements UserContract.Presenter {
+ private UserContract.View view;
+ // ...
+}
+
+public class UserActivity extends AppCompatActivity implements UserContract.View {
+ private UserContract.Presenter presenter;
+ // ...
+}
+```
+
+### 4. 使用 BasePresenter 和 BaseView
+
+```java
+// BaseView
+public interface BaseView {
+ void showLoading();
+ void hideLoading();
+ void showError(String error);
+}
+
+// BasePresenter
+public class BasePresenter {
+ protected V view;
+
+ public void attachView(V view) {
+ this.view = view;
+ }
+
+ public void detachView() {
+ this.view = null;
+ }
+
+ public boolean isViewAttached() {
+ return view != null;
+ }
+}
+
+// 使用
+public interface UserView extends BaseView {
+ void showUsers(List users);
+}
+
+public class UserPresenter extends BasePresenter {
+ // ...
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是 MVP 模式?
+
+**答案:**
+MVP(Model-View-Presenter)是一种软件架构模式:
+- **Model**:数据和业务逻辑
+- **View**:用户界面(通过接口与 Presenter 通信)
+- **Presenter**:处理业务逻辑,协调 Model 和 View
+
+### Q2: MVP 和 MVC 的区别?
+
+**答案:**
+- **MVC**:View 可以直接访问 Model,Controller 处理输入和更新
+- **MVP**:View 和 Model 完全解耦,View 通过接口与 Presenter 通信,Presenter 处理业务逻辑
+
+### Q3: MVP 的优点?
+
+**答案:**
+1. View 和 Model 完全解耦
+2. 易于测试(Presenter 可以独立测试)
+3. 代码复用(Presenter 可以被多个 View 使用)
+4. 职责清晰
+5. 便于维护
+
+### Q4: MVP 的缺点?
+
+**答案:**
+1. 代码量增加(需要定义接口)
+2. 接口过多
+3. Presenter 可能臃肿
+4. 需要手动管理生命周期
+
+### Q5: 如何防止 Presenter 内存泄漏?
+
+**答案:**
+1. 在 onDestroy 中调用 `presenter.detachView()`
+2. Presenter 持有 View 接口的弱引用
+3. 使用 `isViewAttached()` 检查 View 是否可用
+4. 及时取消网络请求和订阅
+
+### Q6: MVP 中如何测试 Presenter?
+
+**答案:**
+1. 创建 Mock View 实现 View 接口
+2. 创建 Mock Model/Repository
+3. 测试 Presenter 的业务逻辑
+4. 验证 Presenter 是否正确调用 View 方法
+
+---
+
+## 总结
+
+MVP 是 Android 开发中常用的架构模式,通过 View 接口实现 View 和 Model 的解耦,使代码更易于测试和维护。虽然代码量会增加,但对于中大型项目来说,这种结构化的方式更有利于长期维护。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统架构/MVVM架构.md b/docs/android面试/系统架构/MVVM架构.md
new file mode 100644
index 0000000..4771d04
--- /dev/null
+++ b/docs/android面试/系统架构/MVVM架构.md
@@ -0,0 +1,738 @@
+# MVVM架构
+
+## 目录
+- [MVVM模式介绍](#mvvm模式介绍)
+- [DataBinding](#databinding)
+- [ViewModel](#viewmodel)
+- [LiveData](#livedata)
+- [MVVM实现示例](#mvvm实现示例)
+- [MVVM优缺点](#mvvm优缺点)
+- [MVVM最佳实践](#mvvm最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## MVVM模式介绍
+
+### MVVM 概念
+
+MVVM(Model-View-ViewModel)是一种软件架构模式:
+
+- **Model**:数据和业务逻辑
+- **View**:用户界面(XML 布局)
+- **ViewModel**:连接 View 和 Model,处理 UI 逻辑
+
+### MVVM 架构图
+
+```
+┌─────────┐
+│ View │ ←─── 显示数据(通过 DataBinding)
+└────┬────┘
+ │ 数据绑定
+ ↓
+┌─────────┐
+│ViewModel │ ←─── 处理 UI 逻辑,持有 LiveData
+└────┬────┘
+ │ 更新
+ ↓
+┌─────────┐
+│ Model │ ←─── 数据和业务逻辑
+└─────────┘
+```
+
+### MVVM 数据流
+
+1. **用户操作 View** → View 通过 DataBinding 或事件绑定调用 ViewModel
+2. **ViewModel 处理** → 调用 Model 获取数据
+3. **Model 返回数据** → ViewModel 更新 LiveData
+4. **LiveData 通知 View** → View 自动更新(通过 DataBinding 或 Observer)
+
+### MVVM 核心特点
+
+1. **数据双向绑定**:View 和 ViewModel 自动同步
+2. **View 被动更新**:通过观察者模式自动更新
+3. **ViewModel 无 View 引用**:不持有 View 引用,避免内存泄漏
+4. **生命周期感知**:LiveData 自动处理生命周期
+
+---
+
+## DataBinding
+
+### DataBinding 简介
+
+DataBinding 是 Android 官方提供的数据绑定框架,可以在 XML 布局中直接绑定数据。
+
+### 启用 DataBinding
+
+```gradle
+android {
+ dataBinding {
+ enabled = true
+ }
+}
+```
+
+### DataBinding 使用
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```java
+// Activity
+public class MainActivity extends AppCompatActivity {
+ private ActivityMainBinding binding;
+ private UserViewModel viewModel;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
+ viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
+ binding.setViewModel(viewModel);
+ binding.setLifecycleOwner(this);
+ }
+}
+```
+
+### DataBinding 表达式
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+---
+
+## ViewModel
+
+### ViewModel 简介
+
+ViewModel 是 Android Jetpack 组件,用于存储和管理 UI 相关的数据,在配置变更(如屏幕旋转)时保持数据。
+
+### ViewModel 特点
+
+1. **生命周期感知**:与 Activity/Fragment 生命周期关联
+2. **配置变更保持**:屏幕旋转等配置变更时数据不丢失
+3. **无 View 引用**:不持有 View 引用,避免内存泄漏
+4. **数据共享**:可以在 Fragment 之间共享数据
+
+### ViewModel 使用
+
+```java
+// ViewModel
+public class UserViewModel extends ViewModel {
+ private MutableLiveData> users = new MutableLiveData<>();
+ private UserRepository repository;
+
+ public UserViewModel() {
+ repository = new UserRepository();
+ loadUsers();
+ }
+
+ public LiveData> getUsers() {
+ return users;
+ }
+
+ public void loadUsers() {
+ repository.getUsers(new UserRepository.Callback>() {
+ @Override
+ public void onSuccess(List data) {
+ users.setValue(data);
+ }
+
+ @Override
+ public void onError(String error) {
+ // 处理错误
+ }
+ });
+ }
+
+ public void addUser(String name, String email) {
+ User user = new User(UUID.randomUUID().toString(), name, email);
+ repository.addUser(user, new UserRepository.Callback() {
+ @Override
+ public void onSuccess(Void data) {
+ loadUsers();
+ }
+
+ @Override
+ public void onError(String error) {
+ // 处理错误
+ }
+ });
+ }
+
+ @Override
+ protected void onCleared() {
+ super.onCleared();
+ // 清理资源
+ }
+}
+
+// Activity
+public class UserActivity extends AppCompatActivity {
+ private UserViewModel viewModel;
+ private ActivityUserBinding binding;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_user);
+
+ viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
+ binding.setViewModel(viewModel);
+ binding.setLifecycleOwner(this);
+
+ observeViewModel();
+ }
+
+ private void observeViewModel() {
+ viewModel.getUsers().observe(this, users -> {
+ // 更新 UI
+ adapter.updateUsers(users);
+ });
+ }
+}
+```
+
+### ViewModel 工厂
+
+```java
+// ViewModelFactory
+public class UserViewModelFactory extends ViewModelProvider.Factory {
+ private UserRepository repository;
+
+ public UserViewModelFactory(UserRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public T create(Class modelClass) {
+ if (modelClass.isAssignableFrom(UserViewModel.class)) {
+ return (T) new UserViewModel(repository);
+ }
+ throw new IllegalArgumentException("Unknown ViewModel class");
+ }
+}
+
+// 使用
+UserRepository repository = new UserRepository();
+UserViewModelFactory factory = new UserViewModelFactory(repository);
+viewModel = ViewModelProviders.of(this, factory).get(UserViewModel.class);
+```
+
+---
+
+## LiveData
+
+### LiveData 简介
+
+LiveData 是 Android Jetpack 组件,是一个可观察的数据持有者,具有生命周期感知能力。
+
+### LiveData 特点
+
+1. **生命周期感知**:自动管理观察者的生命周期
+2. **自动更新**:数据变化时自动通知观察者
+3. **避免内存泄漏**:观察者自动取消订阅
+4. **配置变更保持**:配置变更时数据不丢失
+
+### LiveData 使用
+
+```java
+// ViewModel
+public class UserViewModel extends ViewModel {
+ private MutableLiveData> users = new MutableLiveData<>();
+ private MutableLiveData error = new MutableLiveData<>();
+ private MutableLiveData loading = new MutableLiveData<>();
+
+ public LiveData> getUsers() {
+ return users;
+ }
+
+ public LiveData getError() {
+ return error;
+ }
+
+ public LiveData getLoading() {
+ return loading;
+ }
+
+ public void loadUsers() {
+ loading.setValue(true);
+ repository.getUsers(new UserRepository.Callback>() {
+ @Override
+ public void onSuccess(List data) {
+ loading.setValue(false);
+ users.setValue(data);
+ }
+
+ @Override
+ public void onError(String errorMsg) {
+ loading.setValue(false);
+ error.setValue(errorMsg);
+ }
+ });
+ }
+}
+
+// Activity
+public class UserActivity extends AppCompatActivity {
+ private UserViewModel viewModel;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_user);
+
+ viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
+ observeViewModel();
+ }
+
+ private void observeViewModel() {
+ // 观察用户列表
+ viewModel.getUsers().observe(this, users -> {
+ adapter.updateUsers(users);
+ });
+
+ // 观察错误信息
+ viewModel.getError().observe(this, error -> {
+ Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+ });
+
+ // 观察加载状态
+ viewModel.getLoading().observe(this, isLoading -> {
+ if (isLoading) {
+ progressBar.setVisibility(View.VISIBLE);
+ } else {
+ progressBar.setVisibility(View.GONE);
+ }
+ });
+ }
+}
+```
+
+### LiveData 转换
+
+```java
+// Transformations.map:转换数据
+LiveData userName = Transformations.map(users, users -> {
+ return users.get(0).getName();
+});
+
+// Transformations.switchMap:切换 LiveData
+LiveData> filteredUsers = Transformations.switchMap(searchQuery, query -> {
+ return repository.searchUsers(query);
+});
+
+// 自定义转换
+public class UserNameTransformations {
+ public static LiveData getUserName(LiveData> users) {
+ return Transformations.map(users, userList -> {
+ if (userList != null && !userList.isEmpty()) {
+ return userList.get(0).getName();
+ }
+ return "";
+ });
+ }
+}
+```
+
+### MediatorLiveData
+
+```java
+// 合并多个 LiveData
+public class UserViewModel extends ViewModel {
+ private MediatorLiveData> users = new MediatorLiveData<>();
+ private LiveData> localUsers;
+ private LiveData> remoteUsers;
+
+ public UserViewModel() {
+ localUsers = repository.getLocalUsers();
+ remoteUsers = repository.getRemoteUsers();
+
+ users.addSource(localUsers, users::setValue);
+ users.addSource(remoteUsers, users::setValue);
+ }
+
+ public LiveData> getUsers() {
+ return users;
+ }
+}
+```
+
+---
+
+## MVVM实现示例
+
+### 完整示例:用户列表
+
+```java
+// Model:用户数据模型
+public class User {
+ private String id;
+ private String name;
+ private String email;
+
+ public User(String id, String name, String email) {
+ this.id = id;
+ this.name = name;
+ this.email = email;
+ }
+
+ // Getters and Setters
+ public String getId() { return id; }
+ public String getName() { return name; }
+ public String getEmail() { return email; }
+}
+
+// Model:用户业务逻辑
+public class UserRepository {
+ private List users = new ArrayList<>();
+
+ public void addUser(User user, Callback callback) {
+ new Thread(() -> {
+ try {
+ Thread.sleep(1000);
+ users.add(user);
+ callback.onSuccess();
+ } catch (InterruptedException e) {
+ callback.onError(e.getMessage());
+ }
+ }).start();
+ }
+
+ public void getUsers(Callback> callback) {
+ new Thread(() -> {
+ try {
+ Thread.sleep(500);
+ callback.onSuccess(new ArrayList<>(users));
+ } catch (InterruptedException e) {
+ callback.onError(e.getMessage());
+ }
+ }).start();
+ }
+
+ interface Callback {
+ void onSuccess(T data);
+ void onError(String error);
+ }
+}
+
+// ViewModel
+public class UserViewModel extends ViewModel {
+ private MutableLiveData> users = new MutableLiveData<>();
+ private MutableLiveData error = new MutableLiveData<>();
+ private MutableLiveData loading = new MutableLiveData<>();
+ private UserRepository repository;
+
+ public UserViewModel() {
+ repository = new UserRepository();
+ loadUsers();
+ }
+
+ public LiveData> getUsers() {
+ return users;
+ }
+
+ public LiveData getError() {
+ return error;
+ }
+
+ public LiveData getLoading() {
+ return loading;
+ }
+
+ public void loadUsers() {
+ loading.setValue(true);
+ repository.getUsers(new UserRepository.Callback>() {
+ @Override
+ public void onSuccess(List data) {
+ loading.setValue(false);
+ users.setValue(data);
+ }
+
+ @Override
+ public void onError(String errorMsg) {
+ loading.setValue(false);
+ error.setValue(errorMsg);
+ }
+ });
+ }
+
+ public void addUser(String name, String email) {
+ if (name.isEmpty() || email.isEmpty()) {
+ error.setValue("Name and Email cannot be empty");
+ return;
+ }
+
+ loading.setValue(true);
+ User user = new User(UUID.randomUUID().toString(), name, email);
+ repository.addUser(user, new UserRepository.Callback() {
+ @Override
+ public void onSuccess(Void data) {
+ loading.setValue(false);
+ loadUsers();
+ }
+
+ @Override
+ public void onError(String errorMsg) {
+ loading.setValue(false);
+ error.setValue(errorMsg);
+ }
+ });
+ }
+}
+
+// View:XML 布局(使用 DataBinding)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// View:Activity
+public class UserActivity extends AppCompatActivity {
+ private ActivityUserBinding binding;
+ private UserViewModel viewModel;
+ private UserAdapter adapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_user);
+
+ viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
+ binding.setViewModel(viewModel);
+ binding.setLifecycleOwner(this);
+
+ setupRecyclerView();
+ observeViewModel();
+ }
+
+ private void setupRecyclerView() {
+ adapter = new UserAdapter(new ArrayList<>());
+ binding.rvUsers.setLayoutManager(new LinearLayoutManager(this));
+ binding.rvUsers.setAdapter(adapter);
+ }
+
+ private void observeViewModel() {
+ viewModel.getUsers().observe(this, users -> {
+ adapter.updateUsers(users);
+ });
+
+ viewModel.getError().observe(this, error -> {
+ Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+ });
+ }
+}
+```
+
+---
+
+## MVVM优缺点
+
+### 优点
+
+1. **数据双向绑定**:View 和 ViewModel 自动同步
+2. **代码简洁**:减少样板代码
+3. **易于测试**:ViewModel 可以独立测试
+4. **生命周期感知**:LiveData 自动处理生命周期
+5. **配置变更保持**:ViewModel 在配置变更时保持数据
+
+### 缺点
+
+1. **学习曲线**:需要学习 DataBinding、ViewModel、LiveData
+2. **调试困难**:DataBinding 表达式调试较困难
+3. **性能问题**:DataBinding 可能影响性能(已优化)
+4. **过度绑定**:可能过度使用 DataBinding
+
+---
+
+## MVVM最佳实践
+
+### 1. ViewModel 职责
+
+```java
+// ✅ 好的 ViewModel:只处理 UI 逻辑
+public class UserViewModel extends ViewModel {
+ public void addUser(String name, String email) {
+ // 验证输入
+ if (name.isEmpty() || email.isEmpty()) {
+ error.setValue("Invalid input");
+ return;
+ }
+ // 调用 Repository
+ repository.addUser(name, email, callback);
+ }
+}
+
+// ❌ 不好的 ViewModel:包含业务逻辑
+public class UserViewModel extends ViewModel {
+ public void addUser(String name, String email) {
+ // 业务逻辑不应该在 ViewModel 中
+ if (isValidEmail(email)) {
+ // 复杂的业务逻辑
+ }
+ }
+}
+```
+
+### 2. LiveData 使用
+
+```java
+// ✅ 好的做法:使用 MutableLiveData 私有,暴露 LiveData
+public class UserViewModel extends ViewModel {
+ private MutableLiveData> users = new MutableLiveData<>();
+
+ public LiveData> getUsers() {
+ return users; // 返回不可变的 LiveData
+ }
+}
+
+// ❌ 不好的做法:直接暴露 MutableLiveData
+public class UserViewModel extends ViewModel {
+ public MutableLiveData> users = new MutableLiveData<>();
+}
+```
+
+### 3. DataBinding 使用
+
+```xml
+
+
+
+
+
+
+
+```
+
+### 4. 避免内存泄漏
+
+```java
+// ✅ 好的做法:ViewModel 不持有 View 引用
+public class UserViewModel extends ViewModel {
+ // ViewModel 不持有 Context、View 等引用
+}
+
+// ❌ 不好的做法:ViewModel 持有 View 引用
+public class UserViewModel extends ViewModel {
+ private Activity activity; // 可能导致内存泄漏
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是 MVVM 模式?
+
+**答案:**
+MVVM(Model-View-ViewModel)是一种软件架构模式:
+- **Model**:数据和业务逻辑
+- **View**:用户界面(XML 布局)
+- **ViewModel**:连接 View 和 Model,处理 UI 逻辑
+
+### Q2: MVVM 和 MVP 的区别?
+
+**答案:**
+- **MVP**:View 通过接口与 Presenter 通信,需要手动更新 View
+- **MVVM**:View 通过 DataBinding 和 LiveData 自动更新,ViewModel 不持有 View 引用
+
+### Q3: LiveData 的特点?
+
+**答案:**
+1. 生命周期感知:自动管理观察者的生命周期
+2. 自动更新:数据变化时自动通知观察者
+3. 避免内存泄漏:观察者自动取消订阅
+4. 配置变更保持:配置变更时数据不丢失
+
+### Q4: ViewModel 的作用?
+
+**答案:**
+1. 存储和管理 UI 相关的数据
+2. 在配置变更时保持数据
+3. 处理 UI 逻辑
+4. 不持有 View 引用,避免内存泄漏
+
+### Q5: DataBinding 的优缺点?
+
+**答案:**
+- **优点**:减少样板代码、数据双向绑定、代码简洁
+- **缺点**:学习曲线、调试困难、可能影响性能
+
+### Q6: 如何防止 ViewModel 内存泄漏?
+
+**答案:**
+1. ViewModel 不持有 Context、View 等引用
+2. 使用 Application Context 如果需要 Context
+3. 在 onCleared 中清理资源
+4. 使用 LiveData 自动管理生命周期
+
+---
+
+## 总结
+
+MVVM 是 Android 开发中推荐的架构模式,通过 DataBinding、ViewModel 和 LiveData 实现数据双向绑定和生命周期感知,使代码更简洁、易于测试和维护。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统架构/模块化设计.md b/docs/android面试/系统架构/模块化设计.md
new file mode 100644
index 0000000..e652543
--- /dev/null
+++ b/docs/android面试/系统架构/模块化设计.md
@@ -0,0 +1,566 @@
+# 模块化设计
+
+## 目录
+- [模块化概念](#模块化概念)
+- [模块划分](#模块划分)
+- [模块依赖管理](#模块依赖管理)
+- [模块间解耦](#模块间解耦)
+- [模块化实现](#模块化实现)
+- [模块化最佳实践](#模块化最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 模块化概念
+
+### 什么是模块化?
+
+模块化是将应用程序按照功能或职责拆分成多个独立的模块(Module),每个模块有明确的职责和接口。
+
+### 模块化 vs 组件化
+
+| 特性 | 模块化 | 组件化 |
+|------|--------|--------|
+| 粒度 | 较细,按功能拆分 | 较粗,按业务拆分 |
+| 独立性 | 模块可以独立编译 | 组件可以独立运行 |
+| 复用性 | 模块可以在项目内复用 | 组件可以在项目间复用 |
+| 适用场景 | 中大型项目 | 大型项目、多团队协作 |
+
+### 模块化架构图
+
+```
+┌─────────────────────────────────┐
+│ App Module │
+└─────────────────────────────────┘
+ │
+ ┌──────┴──────┐
+ │ │
+┌───▼───┐ ┌───▼───┐
+│模块A │ │模块B │ ← 功能模块
+│(Module)│ │(Module)│
+└───┬───┘ └───┬───┘
+ │ │
+ └──────┬──────┘
+ │
+ ┌──────▼──────┐
+ │ Base Module │ ← 基础模块
+ └──────────────┘
+```
+
+---
+
+## 模块划分
+
+### 1. 按功能划分
+
+```
+app/
+├── app/ # 主应用模块
+├── module_network/ # 网络模块
+├── module_database/ # 数据库模块
+├── module_cache/ # 缓存模块
+├── module_image/ # 图片加载模块
+├── module_ui/ # UI 组件模块
+└── base/ # 基础模块
+ ├── base_common/ # 公共工具
+ └── base_core/ # 核心功能
+```
+
+### 2. 按层次划分
+
+```
+app/
+├── app/ # 表现层
+├── domain/ # 领域层
+│ ├── domain_user/ # 用户领域
+│ └── domain_order/ # 订单领域
+├── data/ # 数据层
+│ ├── data_repository/ # 数据仓库
+│ └── data_source/ # 数据源
+└── base/ # 基础层
+```
+
+### 3. 按业务划分
+
+```
+app/
+├── app/ # 主应用
+├── feature_login/ # 登录功能
+├── feature_home/ # 首页功能
+├── feature_user/ # 用户功能
+└── shared/ # 共享模块
+ ├── shared_network/ # 网络共享
+ └── shared_ui/ # UI 共享
+```
+
+### 模块划分原则
+
+1. **单一职责**:每个模块只负责一个功能
+2. **高内聚低耦合**:模块内部高内聚,模块间低耦合
+3. **接口清晰**:模块间通过接口通信
+4. **依赖方向**:上层模块依赖下层模块
+
+---
+
+## 模块依赖管理
+
+### 1. 依赖关系
+
+```
+App Module
+ ↓
+Feature Modules(功能模块)
+ ↓
+Shared Modules(共享模块)
+ ↓
+Base Module(基础模块)
+```
+
+### 2. build.gradle 配置
+
+```gradle
+// app/build.gradle
+dependencies {
+ // 依赖功能模块
+ implementation project(':feature_login')
+ implementation project(':feature_home')
+ implementation project(':feature_user')
+
+ // 依赖共享模块
+ implementation project(':shared:shared_network')
+ implementation project(':shared:shared_ui')
+}
+
+// feature_login/build.gradle
+dependencies {
+ // 功能模块依赖共享模块
+ implementation project(':shared:shared_network')
+ implementation project(':shared:shared_ui')
+
+ // 功能模块依赖基础模块
+ implementation project(':base:base_common')
+}
+
+// shared_network/build.gradle
+dependencies {
+ // 共享模块依赖基础模块
+ implementation project(':base:base_common')
+}
+```
+
+### 3. 避免循环依赖
+
+```gradle
+// ❌ 错误:循环依赖
+// module_a 依赖 module_b
+// module_b 依赖 module_a
+
+// ✅ 正确:单向依赖
+// module_a 依赖 module_b
+// module_b 不依赖 module_a
+```
+
+### 4. 依赖版本管理
+
+```gradle
+// 项目 build.gradle
+ext {
+ versions = [
+ 'compileSdk': 30,
+ 'minSdk': 21,
+ 'targetSdk': 30,
+ 'kotlin': '1.5.0',
+ 'retrofit': '2.9.0',
+ 'okhttp': '4.9.0'
+ ]
+}
+
+// 模块 build.gradle
+android {
+ compileSdkVersion versions.compileSdk
+ defaultConfig {
+ minSdkVersion versions.minSdk
+ targetSdkVersion versions.targetSdk
+ }
+}
+
+dependencies {
+ implementation "com.squareup.retrofit2:retrofit:${versions.retrofit}"
+ implementation "com.squareup.okhttp3:okhttp:${versions.okhttp}"
+}
+```
+
+---
+
+## 模块间解耦
+
+### 1. 接口隔离
+
+```java
+// 定义接口
+public interface INetworkModule {
+ void request(String url, Class clazz, Callback callback);
+}
+
+// 模块实现接口
+public class NetworkModule implements INetworkModule {
+ @Override
+ public void request(String url, Class clazz, Callback callback) {
+ // 实现网络请求
+ }
+}
+
+// 其他模块使用接口
+public class LoginModule {
+ private INetworkModule networkModule;
+
+ public LoginModule(INetworkModule networkModule) {
+ this.networkModule = networkModule;
+ }
+
+ public void login(String username, String password) {
+ networkModule.request("/login", User.class, callback);
+ }
+}
+```
+
+### 2. 依赖注入
+
+```java
+// 使用 Dagger2 进行依赖注入
+@Module
+public class NetworkModule {
+ @Provides
+ @Singleton
+ INetworkModule provideNetworkModule() {
+ return new NetworkModuleImpl();
+ }
+}
+
+@Module
+public class LoginModule {
+ @Provides
+ LoginService provideLoginService(INetworkModule networkModule) {
+ return new LoginService(networkModule);
+ }
+}
+
+// 使用
+@Component(modules = {NetworkModule.class, LoginModule.class})
+public interface AppComponent {
+ void inject(MainActivity activity);
+}
+```
+
+### 3. 事件总线
+
+```java
+// 使用 EventBus 解耦
+public class NetworkEvent {
+ private String eventType;
+ private Object data;
+
+ public NetworkEvent(String eventType, Object data) {
+ this.eventType = eventType;
+ this.data = data;
+ }
+}
+
+// 模块A发送事件
+EventBus.getDefault().post(new NetworkEvent("login_success", user));
+
+// 模块B接收事件
+@Subscribe(threadMode = ThreadMode.MAIN)
+public void onNetworkEvent(NetworkEvent event) {
+ if ("login_success".equals(event.getEventType())) {
+ // 处理登录成功事件
+ }
+}
+```
+
+### 4. 服务发现
+
+```java
+// 服务注册中心
+public class ServiceRegistry {
+ private static ServiceRegistry instance;
+ private Map services = new HashMap<>();
+
+ public static ServiceRegistry getInstance() {
+ if (instance == null) {
+ synchronized (ServiceRegistry.class) {
+ if (instance == null) {
+ instance = new ServiceRegistry();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public void register(Class clazz, T service) {
+ services.put(clazz, service);
+ }
+
+ public T get(Class clazz) {
+ return (T) services.get(clazz);
+ }
+}
+
+// 模块注册服务
+ServiceRegistry.getInstance().register(INetworkModule.class, new NetworkModuleImpl());
+
+// 其他模块获取服务
+INetworkModule networkModule = ServiceRegistry.getInstance().get(INetworkModule.class);
+```
+
+---
+
+## 模块化实现
+
+### 1. 项目结构
+
+```
+project/
+├── app/ # 主应用模块
+│ └── build.gradle
+├── feature_login/ # 登录功能模块
+│ └── build.gradle
+├── feature_home/ # 首页功能模块
+│ └── build.gradle
+├── shared/ # 共享模块
+│ ├── shared_network/ # 网络共享
+│ └── shared_ui/ # UI 共享
+├── base/ # 基础模块
+│ ├── base_common/ # 公共工具
+│ └── base_core/ # 核心功能
+└── build.gradle # 项目配置
+```
+
+### 2. 模块配置
+
+```gradle
+// feature_login/build.gradle
+android {
+ compileSdkVersion 30
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ // 依赖共享模块
+ implementation project(':shared:shared_network')
+ implementation project(':shared:shared_ui')
+
+ // 依赖基础模块
+ implementation project(':base:base_common')
+
+ // 第三方库
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+}
+```
+
+### 3. 模块接口定义
+
+```java
+// base_common/src/main/java/com/example/common/INetworkModule.java
+public interface INetworkModule {
+ void request(String url, Class clazz, Callback callback);
+}
+
+// shared_network/src/main/java/com/example/network/NetworkModuleImpl.java
+public class NetworkModuleImpl implements INetworkModule {
+ @Override
+ public void request(String url, Class clazz, Callback callback) {
+ // 实现网络请求
+ }
+}
+```
+
+### 4. 模块初始化
+
+```java
+// Application
+public class MainApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ // 初始化基础模块
+ initBaseModules();
+
+ // 初始化共享模块
+ initSharedModules();
+
+ // 初始化功能模块
+ initFeatureModules();
+ }
+
+ private void initBaseModules() {
+ // 初始化基础模块
+ }
+
+ private void initSharedModules() {
+ // 注册共享模块服务
+ ServiceRegistry.getInstance().register(
+ INetworkModule.class,
+ new NetworkModuleImpl()
+ );
+ }
+
+ private void initFeatureModules() {
+ // 初始化功能模块
+ }
+}
+```
+
+---
+
+## 模块化最佳实践
+
+### 1. 模块职责清晰
+
+```java
+// ✅ 好的模块:职责单一
+// network_module:只负责网络请求
+public class NetworkModule {
+ public void request(String url, Class clazz, Callback callback) {
+ // 网络请求逻辑
+ }
+}
+
+// ❌ 不好的模块:职责过多
+// network_module:既负责网络请求,又负责数据解析、缓存等
+public class NetworkModule {
+ public void request() { }
+ public void parse() { }
+ public void cache() { }
+}
+```
+
+### 2. 接口设计
+
+```java
+// ✅ 好的接口:职责单一,参数清晰
+public interface INetworkModule {
+ void request(String url, Class clazz, Callback callback);
+}
+
+// ❌ 不好的接口:职责过多,参数复杂
+public interface INetworkModule {
+ void request();
+ void parse();
+ void cache();
+ void upload();
+ void download();
+}
+```
+
+### 3. 依赖管理
+
+```gradle
+// ✅ 好的依赖:清晰、单向
+// feature_login → shared_network → base_common
+
+// ❌ 不好的依赖:循环依赖
+// feature_login → feature_home
+// feature_home → feature_login
+```
+
+### 4. 版本管理
+
+```gradle
+// ✅ 好的版本管理:统一管理
+ext {
+ versions = [
+ 'compileSdk': 30,
+ 'retrofit': '2.9.0'
+ ]
+}
+
+// ❌ 不好的版本管理:分散管理
+// 每个模块单独定义版本号
+```
+
+### 5. 测试
+
+```java
+// 每个模块可以独立测试
+// network_module 测试
+public class NetworkModuleTest {
+ @Test
+ public void testRequest() {
+ // 测试网络请求
+ }
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是模块化?
+
+**答案:**
+模块化是将应用程序按照功能或职责拆分成多个独立的模块(Module),每个模块有明确的职责和接口。
+
+### Q2: 模块化和组件化的区别?
+
+**答案:**
+- **模块化**:粒度较细,按功能拆分,模块可以独立编译
+- **组件化**:粒度较粗,按业务拆分,组件可以独立运行
+- **适用场景**:模块化适合中大型项目,组件化适合大型项目、多团队协作
+
+### Q3: 如何划分模块?
+
+**答案:**
+1. 按功能划分:网络模块、数据库模块、缓存模块等
+2. 按层次划分:表现层、领域层、数据层等
+3. 按业务划分:登录功能、首页功能、用户功能等
+4. 遵循单一职责、高内聚低耦合原则
+
+### Q4: 如何管理模块依赖?
+
+**答案:**
+1. 依赖关系:App Module → Feature Modules → Shared Modules → Base Module
+2. 避免循环依赖
+3. 统一版本管理
+4. 使用依赖注入
+
+### Q5: 如何实现模块间解耦?
+
+**答案:**
+1. 接口隔离:定义接口,模块实现接口
+2. 依赖注入:使用 Dagger2 等框架
+3. 事件总线:使用 EventBus 等
+4. 服务发现:使用服务注册中心
+
+### Q6: 模块化的最佳实践?
+
+**答案:**
+1. 模块职责清晰:单一职责原则
+2. 接口设计:职责单一,参数清晰
+3. 依赖管理:清晰、单向依赖
+4. 版本管理:统一管理版本号
+5. 测试:每个模块可以独立测试
+
+---
+
+## 总结
+
+模块化是 Android 应用架构的重要方式,通过将应用拆分成多个独立模块,可以实现代码复用、易于维护、团队协作等优势。在实际项目中,需要合理划分模块、管理模块依赖、实现模块间解耦。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/系统架构/组件化架构.md b/docs/android面试/系统架构/组件化架构.md
new file mode 100644
index 0000000..adf32a9
--- /dev/null
+++ b/docs/android面试/系统架构/组件化架构.md
@@ -0,0 +1,647 @@
+# 组件化架构
+
+## 目录
+- [组件化概念](#组件化概念)
+- [组件化优势](#组件化优势)
+- [组件划分原则](#组件划分原则)
+- [组件间通信](#组件间通信)
+- [路由框架](#路由框架)
+- [组件化实现](#组件化实现)
+- [组件化最佳实践](#组件化最佳实践)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## 组件化概念
+
+### 什么是组件化?
+
+组件化是将一个大型应用拆分成多个独立的、可复用的组件(Module),每个组件可以独立开发、测试、编译和运行。
+
+### 组件化架构图
+
+```
+┌─────────────────────────────────┐
+│ App Module │ ← 主应用模块
+│ (依赖所有业务组件) │
+└─────────────────────────────────┘
+ │
+ ┌──────┴──────┐
+ │ │
+┌───▼───┐ ┌───▼───┐
+│组件A │ │组件B │ ← 业务组件
+│(Module)│ │(Module)│
+└───┬───┘ └───┬───┘
+ │ │
+ └──────┬──────┘
+ │
+ ┌──────▼──────┐
+ │ Common Module │ ← 公共组件
+ │ (基础库) │
+ └──────────────┘
+```
+
+### 组件类型
+
+1. **App Module**:主应用模块,依赖所有业务组件
+2. **业务组件**:独立的功能模块(如登录、首页、个人中心)
+3. **基础组件**:公共库(网络、图片加载、工具类等)
+
+---
+
+## 组件化优势
+
+### 1. 独立开发
+
+- 每个组件可以独立开发、测试
+- 不同团队可以并行开发不同组件
+- 减少代码冲突
+
+### 2. 代码复用
+
+- 组件可以在多个项目中使用
+- 减少重复代码
+- 提高开发效率
+
+### 3. 按需加载
+
+- 可以按需加载组件
+- 减少 APK 体积
+- 提升启动速度
+
+### 4. 易于维护
+
+- 组件职责清晰
+- 修改影响范围小
+- 便于定位问题
+
+### 5. 团队协作
+
+- 团队可以独立负责不同组件
+- 减少沟通成本
+- 提高开发效率
+
+---
+
+## 组件划分原则
+
+### 1. 按业务功能划分
+
+```
+app/
+├── app/ # 主应用模块
+├── module_login/ # 登录组件
+├── module_home/ # 首页组件
+├── module_user/ # 用户中心组件
+├── module_order/ # 订单组件
+└── common/ # 公共组件
+ ├── common_base/ # 基础库
+ ├── common_network/ # 网络库
+ └── common_ui/ # UI 组件库
+```
+
+### 2. 单一职责原则
+
+- 每个组件只负责一个业务功能
+- 组件之间低耦合
+- 组件内部高内聚
+
+### 3. 依赖关系清晰
+
+```
+App Module
+ ↓
+业务组件(相互独立)
+ ↓
+基础组件
+```
+
+### 4. 组件粒度适中
+
+- **过细**:组件过多,管理复杂
+- **过粗**:组件过大,失去组件化意义
+- **适中**:按业务功能合理划分
+
+---
+
+## 组件间通信
+
+### 1. 接口通信
+
+```java
+// 定义接口
+public interface ILoginService {
+ void login(String username, String password, Callback callback);
+ boolean isLogin();
+ void logout();
+}
+
+// 组件A实现接口
+public class LoginServiceImpl implements ILoginService {
+ @Override
+ public void login(String username, String password, Callback callback) {
+ // 登录逻辑
+ }
+}
+
+// 组件B使用接口
+public class HomeActivity extends AppCompatActivity {
+ private ILoginService loginService;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ loginService = ServiceLoader.load(ILoginService.class);
+ if (loginService.isLogin()) {
+ // 已登录
+ }
+ }
+}
+```
+
+### 2. 事件总线通信
+
+```java
+// 使用 EventBus
+public class LoginEvent {
+ private boolean isLogin;
+
+ public LoginEvent(boolean isLogin) {
+ this.isLogin = isLogin;
+ }
+}
+
+// 组件A发送事件
+EventBus.getDefault().post(new LoginEvent(true));
+
+// 组件B接收事件
+@Subscribe(threadMode = ThreadMode.MAIN)
+public void onLoginEvent(LoginEvent event) {
+ if (event.isLogin()) {
+ // 处理登录事件
+ }
+}
+```
+
+### 3. 路由通信
+
+```java
+// 使用 ARouter
+// 组件A跳转到组件B
+ARouter.getInstance()
+ .build("/user/profile")
+ .withString("userId", "123")
+ .navigation();
+
+// 组件B接收参数
+@Route(path = "/user/profile")
+public class ProfileActivity extends AppCompatActivity {
+ @Autowired
+ String userId;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ARouter.getInstance().inject(this);
+ // 使用 userId
+ }
+}
+```
+
+### 4. 服务发现
+
+```java
+// 使用 ServiceLoader
+public class ServiceManager {
+ private static ServiceManager instance;
+ private Map services = new HashMap<>();
+
+ public static ServiceManager getInstance() {
+ if (instance == null) {
+ synchronized (ServiceManager.class) {
+ if (instance == null) {
+ instance = new ServiceManager();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public void register(Class clazz, T service) {
+ services.put(clazz, service);
+ }
+
+ public T get(Class clazz) {
+ return (T) services.get(clazz);
+ }
+}
+
+// 组件A注册服务
+ServiceManager.getInstance().register(ILoginService.class, new LoginServiceImpl());
+
+// 组件B获取服务
+ILoginService loginService = ServiceManager.getInstance().get(ILoginService.class);
+```
+
+---
+
+## 路由框架
+
+### ARouter 使用
+
+#### 1. 集成 ARouter
+
+```gradle
+// build.gradle
+android {
+ defaultConfig {
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [AROUTER_MODULE_NAME: project.getName()]
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation 'com.alibaba:arouter-api:1.5.1'
+ annotationProcessor 'com.alibaba:arouter-compiler:1.5.1'
+}
+```
+
+#### 2. 初始化
+
+```java
+// Application
+public class MyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (BuildConfig.DEBUG) {
+ ARouter.openLog();
+ ARouter.openDebug();
+ }
+ ARouter.init(this);
+ }
+}
+```
+
+#### 3. 定义路由
+
+```java
+// 组件A:登录页面
+@Route(path = "/login/activity")
+public class LoginActivity extends AppCompatActivity {
+ // ...
+}
+
+// 组件B:用户中心
+@Route(path = "/user/profile")
+public class ProfileActivity extends AppCompatActivity {
+ @Autowired
+ String userId;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ARouter.getInstance().inject(this);
+ }
+}
+```
+
+#### 4. 路由跳转
+
+```java
+// 普通跳转
+ARouter.getInstance()
+ .build("/login/activity")
+ .navigation();
+
+// 带参数跳转
+ARouter.getInstance()
+ .build("/user/profile")
+ .withString("userId", "123")
+ .withInt("age", 25)
+ .navigation();
+
+// 带回调跳转
+ARouter.getInstance()
+ .build("/user/profile")
+ .navigation(this, new NavCallback() {
+ @Override
+ public void onArrival(Postcard postcard) {
+ // 到达目标页面
+ }
+
+ @Override
+ public void onFound(Postcard postcard) {
+ // 找到目标页面
+ }
+
+ @Override
+ public void onLost(Postcard postcard) {
+ // 未找到目标页面
+ }
+ });
+```
+
+#### 5. 路由拦截器
+
+```java
+@Interceptor(priority = 1, name = "login")
+public class LoginInterceptor implements IInterceptor {
+ @Override
+ public void process(Postcard postcard, InterceptorCallback callback) {
+ if (postcard.getPath().equals("/user/profile")) {
+ if (!isLogin()) {
+ // 未登录,跳转到登录页
+ ARouter.getInstance()
+ .build("/login/activity")
+ .navigation();
+ callback.onInterrupt(new RuntimeException("请先登录"));
+ } else {
+ callback.onContinue(postcard);
+ }
+ } else {
+ callback.onContinue(postcard);
+ }
+ }
+
+ @Override
+ public void init(Context context) {
+ // 初始化
+ }
+}
+```
+
+---
+
+## 组件化实现
+
+### 1. 项目结构
+
+```
+project/
+├── app/ # 主应用模块
+│ └── build.gradle
+├── module_login/ # 登录组件
+│ └── build.gradle
+├── module_home/ # 首页组件
+│ └── build.gradle
+├── module_user/ # 用户中心组件
+│ └── build.gradle
+├── common/ # 公共组件
+│ ├── common_base/ # 基础库
+│ ├── common_network/ # 网络库
+│ └── common_ui/ # UI 组件库
+└── build.gradle # 项目配置
+```
+
+### 2. build.gradle 配置
+
+```gradle
+// 项目 build.gradle
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:4.1.0'
+ classpath 'com.alibaba:arouter-register:1.0.2'
+ }
+}
+
+// app/build.gradle
+dependencies {
+ if (isModule.toBoolean()) {
+ // 组件化模式:依赖各个业务组件
+ implementation project(':module_login')
+ implementation project(':module_home')
+ implementation project(':module_user')
+ }
+ // 依赖公共组件
+ implementation project(':common:common_base')
+ implementation project(':common:common_network')
+}
+
+// module_login/build.gradle
+android {
+ if (isModule.toBoolean()) {
+ // 组件化模式:作为 Library
+ apply plugin: 'com.android.library'
+ } else {
+ // 独立模式:作为 Application
+ apply plugin: 'com.android.application'
+ }
+}
+
+dependencies {
+ // 依赖公共组件
+ implementation project(':common:common_base')
+ implementation project(':common:common_network')
+}
+```
+
+### 3. gradle.properties 配置
+
+```properties
+# 是否组件化模式
+isModule=false
+
+# 组件化模式:true(作为 Library)
+# 独立模式:false(作为 Application)
+```
+
+### 4. AndroidManifest 配置
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 5. 组件 Application
+
+```java
+// 组件独立 Application
+public class LoginApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ // 组件初始化
+ }
+}
+
+// 主应用 Application
+public class MainApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ // 初始化公共组件
+ initCommon();
+
+ // 初始化业务组件
+ if (BuildConfig.IS_MODULE) {
+ initModules();
+ }
+ }
+
+ private void initModules() {
+ // 初始化各个业务组件
+ }
+}
+```
+
+---
+
+## 组件化最佳实践
+
+### 1. 组件依赖规则
+
+```
+业务组件 → 基础组件
+App Module → 所有组件
+业务组件之间不相互依赖
+```
+
+### 2. 资源命名规范
+
+```xml
+
+
+登录
+#FFFFFF
+
+
+首页
+#FFFFFF
+```
+
+### 3. 接口定义
+
+```java
+// 在 common_base 中定义接口
+public interface ILoginService {
+ void login(String username, String password, Callback callback);
+}
+
+// 在 module_login 中实现接口
+public class LoginServiceImpl implements ILoginService {
+ // 实现
+}
+
+// 在 App Module 中注册
+ServiceManager.getInstance().register(ILoginService.class, new LoginServiceImpl());
+```
+
+### 4. 组件测试
+
+```java
+// 每个组件可以独立运行和测试
+// 在独立模式下,组件可以作为独立应用运行
+if (!isModule.toBoolean()) {
+ // 独立模式配置
+}
+```
+
+### 5. 版本管理
+
+```gradle
+// 统一管理版本号
+ext {
+ compileSdkVersion = 30
+ minSdkVersion = 21
+ targetSdkVersion = 30
+ versionCode = 1
+ versionName = "1.0.0"
+}
+```
+
+---
+
+## 面试常见问题
+
+### Q1: 什么是组件化?
+
+**答案:**
+组件化是将一个大型应用拆分成多个独立的、可复用的组件(Module),每个组件可以独立开发、测试、编译和运行。
+
+### Q2: 组件化的优势?
+
+**答案:**
+1. 独立开发:每个组件可以独立开发、测试
+2. 代码复用:组件可以在多个项目中使用
+3. 按需加载:可以按需加载组件
+4. 易于维护:组件职责清晰
+5. 团队协作:团队可以独立负责不同组件
+
+### Q3: 如何划分组件?
+
+**答案:**
+1. 按业务功能划分
+2. 单一职责原则
+3. 依赖关系清晰
+4. 组件粒度适中
+
+### Q4: 组件间如何通信?
+
+**答案:**
+1. 接口通信:定义接口,组件实现接口
+2. 事件总线:使用 EventBus 等事件总线
+3. 路由通信:使用 ARouter 等路由框架
+4. 服务发现:使用 ServiceLoader 等服务发现机制
+
+### Q5: ARouter 的作用?
+
+**答案:**
+ARouter 是阿里巴巴开源的 Android 路由框架,用于:
+1. 页面跳转:组件间页面跳转
+2. 参数传递:页面间参数传递
+3. 拦截器:路由拦截和权限控制
+4. 服务发现:组件间服务调用
+
+### Q6: 组件化的最佳实践?
+
+**答案:**
+1. 组件依赖规则:业务组件 → 基础组件
+2. 资源命名规范:使用组件前缀
+3. 接口定义:在公共组件中定义接口
+4. 组件测试:每个组件可以独立测试
+5. 版本管理:统一管理版本号
+
+---
+
+## 总结
+
+组件化是大型 Android 应用架构的重要方式,通过将应用拆分成多个独立组件,可以实现独立开发、代码复用、易于维护等优势。在实际项目中,需要合理划分组件、设计组件间通信机制、使用路由框架等。
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/网络编程/HTTP与HTTPS.md b/docs/android面试/网络编程/HTTP与HTTPS.md
new file mode 100644
index 0000000..bb7c947
--- /dev/null
+++ b/docs/android面试/网络编程/HTTP与HTTPS.md
@@ -0,0 +1,338 @@
+# HTTP与HTTPS
+
+## 目录
+- [HTTP协议](#http协议)
+- [HTTPS协议](#https协议)
+- [HTTP/2](#http2)
+- [HTTP/3](#http3)
+- [请求方法](#请求方法)
+- [状态码](#状态码)
+- [请求头与响应头](#请求头与响应头)
+- [安全机制](#安全机制)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## HTTP协议
+
+### HTTP 简介
+
+```java
+// HTTP:HyperText Transfer Protocol
+// 超文本传输协议
+// 应用层协议
+// 基于 TCP/IP
+```
+
+### HTTP 特点
+
+1. **无状态**:每次请求独立,不保存状态
+2. **请求-响应**:客户端请求,服务器响应
+3. **明文传输**:数据不加密(HTTPS 加密)
+
+### HTTP 请求格式
+
+```
+请求行:方法 路径 协议版本
+请求头:键值对
+空行
+请求体:数据(可选)
+
+示例:
+GET /index.html HTTP/1.1
+Host: www.example.com
+User-Agent: Mozilla/5.0
+```
+
+### HTTP 响应格式
+
+```
+状态行:协议版本 状态码 状态描述
+响应头:键值对
+空行
+响应体:数据
+
+示例:
+HTTP/1.1 200 OK
+Content-Type: text/html
+Content-Length: 1234
+
+...
+```
+
+---
+
+## HTTPS协议
+
+### HTTPS 简介
+
+```java
+// HTTPS:HTTP over SSL/TLS
+// 安全的 HTTP 协议
+// 使用 SSL/TLS 加密
+```
+
+### HTTPS 工作原理
+
+```
+1. 客户端请求 HTTPS 连接
+2. 服务器返回证书
+3. 客户端验证证书
+4. 客户端生成对称密钥,用服务器公钥加密
+5. 服务器用私钥解密,获得对称密钥
+6. 使用对称密钥加密通信
+```
+
+### SSL/TLS 握手
+
+```java
+// SSL/TLS 握手过程
+// 1. Client Hello:客户端发送支持的加密算法
+// 2. Server Hello:服务器选择加密算法,返回证书
+// 3. Client Key Exchange:客户端生成密钥,用服务器公钥加密
+// 4. Change Cipher Spec:切换到加密通信
+// 5. Finished:握手完成
+```
+
+---
+
+## HTTP/2
+
+### HTTP/2 特性
+
+1. **多路复用**:一个连接可以处理多个请求
+2. **头部压缩**:压缩请求头和响应头
+3. **服务器推送**:服务器可以主动推送资源
+4. **二进制分帧**:使用二进制格式
+
+### HTTP/2 vs HTTP/1.1
+
+| 特性 | HTTP/1.1 | HTTP/2 |
+|------|----------|--------|
+| 连接 | 多个连接 | 单个连接 |
+| 多路复用 | ❌ | ✅ |
+| 头部压缩 | ❌ | ✅ |
+| 服务器推送 | ❌ | ✅ |
+
+---
+
+## HTTP/3
+
+### HTTP/3 特性
+
+1. **基于 UDP**:使用 QUIC 协议
+2. **更快连接**:减少握手时间
+3. **更好的拥塞控制**
+4. **连接迁移**:切换网络不断开连接
+
+---
+
+## 请求方法
+
+### GET
+
+```java
+// GET:获取资源
+// 参数在 URL 中
+// 幂等性:是
+// 安全性:是(不修改资源)
+
+GET /user?id=1 HTTP/1.1
+```
+
+### POST
+
+```java
+// POST:创建资源
+// 参数在请求体中
+// 幂等性:否
+// 安全性:否(修改资源)
+
+POST /user HTTP/1.1
+Content-Type: application/json
+
+{"name": "John", "email": "john@example.com"}
+```
+
+### PUT
+
+```java
+// PUT:更新资源(完整更新)
+// 幂等性:是
+// 安全性:否
+
+PUT /user/1 HTTP/1.1
+{"name": "Jane", "email": "jane@example.com"}
+```
+
+### PATCH
+
+```java
+// PATCH:更新资源(部分更新)
+// 幂等性:否
+// 安全性:否
+
+PATCH /user/1 HTTP/1.1
+{"name": "Jane"}
+```
+
+### DELETE
+
+```java
+// DELETE:删除资源
+// 幂等性:是
+// 安全性:否
+
+DELETE /user/1 HTTP/1.1
+```
+
+---
+
+## 状态码
+
+### 2xx 成功
+
+```java
+// 200 OK:请求成功
+// 201 Created:创建成功
+// 204 No Content:成功但无内容
+```
+
+### 3xx 重定向
+
+```java
+// 301 Moved Permanently:永久重定向
+// 302 Found:临时重定向
+// 304 Not Modified:未修改(使用缓存)
+```
+
+### 4xx 客户端错误
+
+```java
+// 400 Bad Request:请求错误
+// 401 Unauthorized:未授权
+// 403 Forbidden:禁止访问
+// 404 Not Found:资源不存在
+```
+
+### 5xx 服务器错误
+
+```java
+// 500 Internal Server Error:服务器错误
+// 502 Bad Gateway:网关错误
+// 503 Service Unavailable:服务不可用
+```
+
+---
+
+## 请求头与响应头
+
+### 常用请求头
+
+```java
+// Host:服务器地址
+Host: www.example.com
+
+// User-Agent:客户端信息
+User-Agent: Mozilla/5.0
+
+// Content-Type:请求体类型
+Content-Type: application/json
+
+// Authorization:认证信息
+Authorization: Bearer token
+
+// Cookie:Cookie 信息
+Cookie: session_id=123
+```
+
+### 常用响应头
+
+```java
+// Content-Type:响应体类型
+Content-Type: application/json
+
+// Content-Length:响应体长度
+Content-Length: 1234
+
+// Set-Cookie:设置 Cookie
+Set-Cookie: session_id=123; Path=/
+
+// Cache-Control:缓存控制
+Cache-Control: max-age=3600
+
+// Location:重定向地址
+Location: https://www.example.com/new
+```
+
+---
+
+## 安全机制
+
+### 1. HTTPS
+
+```java
+// 使用 HTTPS 加密传输
+// 防止数据被窃听和篡改
+```
+
+### 2. 认证
+
+```java
+// Basic 认证
+Authorization: Basic base64(username:password)
+
+// Bearer 认证(Token)
+Authorization: Bearer token
+
+// OAuth 2.0
+Authorization: Bearer access_token
+```
+
+### 3. CORS
+
+```java
+// 跨域资源共享
+Access-Control-Allow-Origin: *
+Access-Control-Allow-Methods: GET, POST
+Access-Control-Allow-Headers: Content-Type
+```
+
+---
+
+## 面试常见问题
+
+### Q1: HTTP 和 HTTPS 的区别?
+
+**答案:**
+- **HTTP**:明文传输,不加密
+- **HTTPS**:使用 SSL/TLS 加密传输,更安全
+
+### Q2: HTTP 请求方法?
+
+**答案:**
+- GET:获取资源
+- POST:创建资源
+- PUT:更新资源(完整)
+- PATCH:更新资源(部分)
+- DELETE:删除资源
+
+### Q3: HTTP 状态码?
+
+**答案:**
+- 2xx:成功
+- 3xx:重定向
+- 4xx:客户端错误
+- 5xx:服务器错误
+
+### Q4: HTTP/2 的特性?
+
+**答案:**
+1. 多路复用
+2. 头部压缩
+3. 服务器推送
+4. 二进制分帧
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/网络编程/OkHttp原理.md b/docs/android面试/网络编程/OkHttp原理.md
new file mode 100644
index 0000000..bea0cd8
--- /dev/null
+++ b/docs/android面试/网络编程/OkHttp原理.md
@@ -0,0 +1,329 @@
+# OkHttp原理
+
+## 目录
+- [OkHttp架构](#okhttp架构)
+- [拦截器机制](#拦截器机制)
+- [连接池](#连接池)
+- [缓存机制](#缓存机制)
+- [请求流程](#请求流程)
+- [响应处理](#响应处理)
+- [OkHttp源码分析](#okhttp源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## OkHttp架构
+
+### 架构图
+
+```
+┌─────────────┐
+│ Client │ ←─── 客户端
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Interceptor│ ←─── 拦截器链
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Connection │ ←─── 连接管理
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Network │ ←─── 网络层
+└─────────────┘
+```
+
+### 核心组件
+
+```java
+// OkHttpClient:客户端配置
+OkHttpClient client = new OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .build();
+
+// Request:请求
+Request request = new Request.Builder()
+ .url("https://www.example.com")
+ .build();
+
+// Call:执行请求
+Call call = client.newCall(request);
+Response response = call.execute();
+```
+
+---
+
+## 拦截器机制
+
+### 拦截器链
+
+```java
+// 拦截器链:责任链模式
+// 请求:Client → Interceptor1 → Interceptor2 → ... → Network
+// 响应:Network → ... → Interceptor2 → Interceptor1 → Client
+
+public class MyInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+
+ // 请求前处理
+ Request newRequest = request.newBuilder()
+ .addHeader("Authorization", "Bearer token")
+ .build();
+
+ // 执行请求
+ Response response = chain.proceed(newRequest);
+
+ // 响应后处理
+ return response;
+ }
+}
+```
+
+### 内置拦截器
+
+```java
+// 1. RetryAndFollowUpInterceptor:重试和重定向
+// 2. BridgeInterceptor:添加请求头
+// 3. CacheInterceptor:缓存处理
+// 4. ConnectInterceptor:建立连接
+// 5. CallServerInterceptor:发送请求
+```
+
+### 自定义拦截器
+
+```java
+// 日志拦截器
+public class LoggingInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ long startTime = System.currentTimeMillis();
+
+ Response response = chain.proceed(request);
+
+ long endTime = System.currentTimeMillis();
+ Log.d("OkHttp", String.format(
+ "Request: %s, Duration: %dms",
+ request.url(), endTime - startTime
+ ));
+
+ return response;
+ }
+}
+
+// 使用
+OkHttpClient client = new OkHttpClient.Builder()
+ .addInterceptor(new LoggingInterceptor())
+ .build();
+```
+
+---
+
+## 连接池
+
+### 连接池原理
+
+```java
+// ConnectionPool:连接池
+// 复用 TCP 连接,减少建立连接的开销
+
+// 连接池配置
+ConnectionPool pool = new ConnectionPool(10, 5, TimeUnit.MINUTES);
+// 最大连接数:10
+// 空闲连接存活时间:5分钟
+
+OkHttpClient client = new OkHttpClient.Builder()
+ .connectionPool(pool)
+ .build();
+```
+
+### 连接复用
+
+```java
+// HTTP/1.1:Keep-Alive
+// 同一个连接可以处理多个请求
+
+// HTTP/2:多路复用
+// 一个连接可以同时处理多个请求
+```
+
+---
+
+## 缓存机制
+
+### 缓存配置
+
+```java
+// 配置缓存
+int cacheSize = 10 * 1024 * 1024; // 10MB
+Cache cache = new Cache(context.getCacheDir(), cacheSize);
+
+OkHttpClient client = new OkHttpClient.Builder()
+ .cache(cache)
+ .build();
+```
+
+### 缓存策略
+
+```java
+// 使用 Cache-Control 头控制缓存
+Request request = new Request.Builder()
+ .url("https://www.example.com")
+ .cacheControl(CacheControl.FORCE_CACHE) // 强制使用缓存
+ .build();
+
+// 或
+Request request = new Request.Builder()
+ .url("https://www.example.com")
+ .cacheControl(new CacheControl.Builder()
+ .maxAge(3600, TimeUnit.SECONDS)
+ .build())
+ .build();
+```
+
+---
+
+## 请求流程
+
+### 请求执行流程
+
+```
+1. 创建 Request
+2. 创建 Call
+3. 执行拦截器链
+ - RetryAndFollowUpInterceptor
+ - BridgeInterceptor
+ - CacheInterceptor
+ - ConnectInterceptor
+ - CallServerInterceptor
+4. 返回 Response
+```
+
+### 异步请求
+
+```java
+// 异步请求
+Call call = client.newCall(request);
+call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ // 请求失败
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ // 请求成功
+ String body = response.body().string();
+ }
+});
+```
+
+---
+
+## 响应处理
+
+### 响应解析
+
+```java
+// 同步请求
+Response response = call.execute();
+if (response.isSuccessful()) {
+ String body = response.body().string();
+ // 处理响应体
+}
+
+// 异步请求
+call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (response.isSuccessful()) {
+ String body = response.body().string();
+ // 处理响应体
+ }
+ }
+});
+```
+
+### 响应流
+
+```java
+// 读取响应流
+ResponseBody body = response.body();
+InputStream is = body.byteStream();
+// 使用流读取
+```
+
+---
+
+## OkHttp源码分析
+
+### 核心类
+
+```java
+// OkHttpClient:客户端配置
+// Request:请求对象
+// Response:响应对象
+// Call:执行请求的接口
+// RealCall:Call 的实现
+// Interceptor:拦截器接口
+// ConnectionPool:连接池
+// Cache:缓存
+```
+
+### 关键流程
+
+```java
+// 1. 创建 Call
+Call call = client.newCall(request);
+
+// 2. 执行请求
+Response response = call.execute();
+
+// 3. 拦截器链处理
+// 4. 建立连接
+// 5. 发送请求
+// 6. 接收响应
+```
+
+---
+
+## 面试常见问题
+
+### Q1: OkHttp 的拦截器机制?
+
+**答案:**
+- 使用责任链模式
+- 请求和响应都经过拦截器链
+- 可以添加自定义拦截器
+
+### Q2: OkHttp 的连接池?
+
+**答案:**
+- 复用 TCP 连接
+- 减少建立连接的开销
+- 支持 HTTP/1.1 Keep-Alive 和 HTTP/2 多路复用
+
+### Q3: OkHttp 的缓存机制?
+
+**答案:**
+- 使用 Cache-Control 头控制缓存
+- 支持内存和磁盘缓存
+- 自动处理缓存验证
+
+### Q4: OkHttp 的请求流程?
+
+**答案:**
+1. 创建 Request
+2. 创建 Call
+3. 执行拦截器链
+4. 建立连接
+5. 发送请求
+6. 接收响应
+
+---
+
+*最后更新:2024年*
diff --git a/docs/android面试/网络编程/Retrofit原理.md b/docs/android面试/网络编程/Retrofit原理.md
new file mode 100644
index 0000000..6c55f95
--- /dev/null
+++ b/docs/android面试/网络编程/Retrofit原理.md
@@ -0,0 +1,320 @@
+# Retrofit原理
+
+## 目录
+- [Retrofit架构](#retrofit架构)
+- [动态代理](#动态代理)
+- [注解处理](#注解处理)
+- [请求适配器](#请求适配器)
+- [响应转换器](#响应转换器)
+- [Retrofit与OkHttp](#retrofit与okhttp)
+- [Retrofit源码分析](#retrofit源码分析)
+- [面试常见问题](#面试常见问题)
+
+---
+
+## Retrofit架构
+
+### 架构图
+
+```
+┌─────────────┐
+│ Interface │ ←─── API 接口定义
+└──────┬──────┘
+ │
+┌──────▼──────┐
+│ Retrofit │ ←─── Retrofit 核心
+└──────┬──────┘
+ │
+┌──────┬──────┐
+│ │ │
+┌──────▼──────┐ ┌──────▼──────┐
+│CallAdapter │ │Converter │
+└──────┬──────┘ └──────┬──────┘
+ │ │
+┌──────▼───────────────▼──────┐
+│ OkHttp │ ←─── 底层 HTTP 客户端
+└─────────────────────────────┘
+```
+
+### 核心组件
+
+```java
+// Retrofit:核心类
+Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("https://api.example.com/")
+ .addConverterFactory(GsonConverterFactory.create())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .build();
+
+// API 接口
+public interface ApiService {
+ @GET("user/{id}")
+ Call getUser(@Path("id") int id);
+}
+
+// 创建代理对象
+ApiService api = retrofit.create(ApiService.class);
+```
+
+---
+
+## 动态代理
+
+### 代理模式
+
+```java
+// Retrofit 使用动态代理创建 API 接口实现
+// 1. 定义接口
+public interface ApiService {
+ @GET("user/{id}")
+ Call getUser(@Path("id") int id);
+}
+
+// 2. Retrofit 创建代理对象
+ApiService api = retrofit.create(ApiService.class);
+
+// 3. 调用方法时,代理对象拦截调用
+// 4. 解析注解,构建 Request
+// 5. 使用 OkHttp 执行请求
+```
+
+### 代理实现
+
+```java
+// Retrofit 内部使用 Proxy.newProxyInstance 创建代理
+ApiService api = (ApiService) Proxy.newProxyInstance(
+ ApiService.class.getClassLoader(),
+ new Class[]{ApiService.class},
+ new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) {
+ // 解析方法注解
+ // 构建 Request
+ // 执行请求
+ return null;
+ }
+ }
+);
+```
+
+---
+
+## 注解处理
+
+### 请求方法注解
+
+```java
+// @GET:GET 请求
+@GET("user/{id}")
+Call getUser(@Path("id") int id);
+
+// @POST:POST 请求
+@POST("user")
+Call createUser(@Body User user);
+
+// @PUT:PUT 请求
+@PUT("user/{id}")
+Call updateUser(@Path("id") int id, @Body User user);
+
+// @DELETE:DELETE 请求
+@DELETE("user/{id}")
+Call deleteUser(@Path("id") int id);
+```
+
+### 参数注解
+
+```java
+// @Path:路径参数
+@GET("user/{id}")
+Call getUser(@Path("id") int id);
+
+// @Query:查询参数
+@GET("user")
+Call