测试
This commit is contained in:
52
.obsidian/workspace.json
vendored
52
.obsidian/workspace.json
vendored
@@ -13,12 +13,12 @@
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "docs/Obsidian笔记体系/Areas/01-系统启动流程/Zygote进程启动.md",
|
||||
"file": "docs/Obsidian笔记体系/Areas/05-进程与线程通信/README.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Zygote进程启动"
|
||||
"title": "README"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -185,33 +185,33 @@
|
||||
},
|
||||
"active": "f1ecba89214e3cc5",
|
||||
"lastOpenFiles": [
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/SystemServer核心服务.md",
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/Launcher启动流程.md",
|
||||
"Zygote进程启动.md",
|
||||
"SystemServer核心服务.md",
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/Bootloader到Init.md",
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/README.md",
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/Zygote进程启动.md",
|
||||
"Launcher启动流程.md",
|
||||
"Bootloader到Init.md",
|
||||
"docs/Obsidian笔记体系/README.md",
|
||||
"docs/Obsidian笔记体系/Areas/05-进程与线程通信/Handler机制源码解析.md",
|
||||
"docs/Obsidian笔记体系/Areas/05-进程与线程通信/README.md",
|
||||
"docs/Obsidian笔记体系/Areas/06-性能优化体系/内存优化(LeakCanary原理).md",
|
||||
"docs/Obsidian笔记体系/Areas/06-性能优化体系/启动优化方法论.md",
|
||||
"docs/cursor/cursor.md",
|
||||
"docs/Obsidian笔记体系/Templates/源码解析模板.md",
|
||||
"docs/Obsidian笔记体系/Templates/问题排查模板.md",
|
||||
"docs/Obsidian笔记体系/Templates/技术方案设计模板.md",
|
||||
"docs/Obsidian笔记体系/Templates/会议记录模板.md",
|
||||
"docs/Obsidian笔记体系/Areas/05-进程与线程通信/Binder机制(内核到Java层).md",
|
||||
"docs/Obsidian笔记体系/Areas/04-资源与包管理/Resource资源加载机制.md",
|
||||
"docs/Obsidian笔记体系/Areas/05-进程与线程通信/AIDL与HIDL使用与原理.md",
|
||||
"docs/Obsidian笔记体系/Areas/05-进程与线程通信/跨进程同步与锁优化.md",
|
||||
"docs/Obsidian笔记体系/Areas/06-性能优化体系/功耗优化工具链.md",
|
||||
"docs/Obsidian笔记体系/Areas/04-资源与包管理/PackageManagerService.md",
|
||||
"文档完善提示词模板.md",
|
||||
"docs/Obsidian笔记体系/Areas/04-资源与包管理/动态加载与热修复原理.md",
|
||||
"Resource资源加载机制.md",
|
||||
"README.md",
|
||||
"docs/Obsidian笔记体系/Areas/07-系统安全/密钥存储与加密.md",
|
||||
"docs/Obsidian笔记体系/Areas/07-系统安全/漏洞案例库.md",
|
||||
"docs/Obsidian/2026-01-05 个人文档管理.md",
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/Bootloader到Init.md.bak",
|
||||
"docs/学习笔记/gerrit分支规范.md",
|
||||
"docs/Obsidian笔记体系/MOCs/Android Framework知识体系图.md",
|
||||
"docs/Obsidian笔记体系/MOCs/源码阅读地图.md",
|
||||
"docs/Obsidian笔记体系/MOCs/高频问题索引.md",
|
||||
"docs/Obsidian笔记体系/Daily/templates/每日模板.md",
|
||||
"docs/Obsidian笔记体系/Daily/2024-06-02.md",
|
||||
"docs/Obsidian笔记体系/Daily/2024-06-01.md",
|
||||
"docs/Obsidian笔记体系/Config/插件列表与配置.md",
|
||||
"docs/Obsidian笔记体系/Areas/02-Activity管理/生命周期深度解析.md",
|
||||
"docs/Obsidian笔记体系/Areas/02-Activity管理/异常恢复机制.md",
|
||||
"PackageManagerService.md",
|
||||
"docs/Obsidian笔记体系/Areas/03-Window系统/README.md",
|
||||
"docs/Obsidian笔记体系/Areas/04-资源与包管理/README.md",
|
||||
"动态加载与热修复原理.md",
|
||||
"docs/Obsidian笔记体系/Areas/03-Window系统/WindowManagerService架构.md",
|
||||
"docs/Obsidian笔记体系/Areas/03-Window系统/SurfaceFlinger交互流程.md",
|
||||
"docs/Obsidian笔记体系/Areas/03-Window系统/窗口类型与层级.md",
|
||||
"docs/Obsidian笔记体系/Areas/01-系统启动流程/Bootloader到Init.md.bak",
|
||||
"docs/Obsidian笔记体系/Config/自定义脚本/源码链接生成器.py",
|
||||
"docs/Obsidian笔记体系/Config/自定义脚本/自动生成日报.js",
|
||||
"docs/Obsidian笔记体系/Config/主题与样式.css",
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
# Bootloader到Init:Android系统启动的第一阶段
|
||||
|
||||
Android系统启动是一个复杂的过程,从硬件上电到用户界面呈现,涉及多个阶段的协同工作。本文详细分析从Bootloader到Init进程的完整启动流程。
|
||||
|
||||
## 启动流程概览
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[硬件上电] --> B[Bootloader执行]
|
||||
B --> C[加载内核]
|
||||
C --> D[内核初始化]
|
||||
D --> E[挂载文件系统]
|
||||
E --> F[启动Init进程]
|
||||
F --> G[解析init.rc]
|
||||
G --> H[启动系统服务]
|
||||
```
|
||||
|
||||
## 1. Bootloader阶段
|
||||
|
||||
### 1.1 硬件初始化
|
||||
- **电源管理**:初始化CPU、内存、时钟等硬件
|
||||
- **外设检测**:识别存储设备、显示设备等
|
||||
- **安全验证**:验证引导镜像的完整性和签名
|
||||
|
||||
### 1.2 引导加载程序
|
||||
- **Primary Bootloader**:芯片厂商提供的初始引导程序
|
||||
- **Secondary Bootloader**:设备厂商定制的引导程序(如U-Boot)
|
||||
- **引导参数传递**:通过设备树(Device Tree)或ATAGS向内核传递参数
|
||||
|
||||
### 1.3 内核加载
|
||||
- **镜像选择**:根据启动模式选择相应的内核镜像
|
||||
- **内存布局**:设置内核加载地址和内存映射
|
||||
- **跳转到内核**:将控制权交给内核入口点
|
||||
|
||||
## 2. 内核启动阶段
|
||||
|
||||
### 2.1 内核初始化
|
||||
- **体系结构相关初始化**:CPU架构特定的设置
|
||||
- **内存管理初始化**:建立页表,初始化内存分配器
|
||||
- **设备树解析**:解析硬件配置信息
|
||||
|
||||
### 2.2 驱动加载
|
||||
- **早期驱动**:控制台、定时器等基础驱动
|
||||
- **存储驱动**:加载文件系统所需的驱动
|
||||
- **设备初始化**:初始化各种硬件设备
|
||||
|
||||
### 2.3 挂载文件系统
|
||||
- **根文件系统**:挂载ramdisk或实际存储
|
||||
- **必要目录创建**:创建/dev、/proc、/sys等目录
|
||||
- **设备节点创建**:创建设备文件节点
|
||||
|
||||
## 3. Init进程启动
|
||||
|
||||
### 3.1 Init进程的职责
|
||||
- **第一个用户空间进程**:PID为1的特殊进程
|
||||
- **系统服务管理**:启动和管理所有系统服务
|
||||
- **进程监控**:监控子进程状态,处理僵尸进程
|
||||
|
||||
### 3.2 init.rc配置文件
|
||||
```bash
|
||||
# init.rc示例片段
|
||||
on early-init
|
||||
# 早期初始化
|
||||
mkdir /dev
|
||||
mount tmpfs tmpfs /dev
|
||||
|
||||
on init
|
||||
# 主初始化阶段
|
||||
symlink /system/bin /bin
|
||||
|
||||
on boot
|
||||
# 启动系统服务
|
||||
start servicemanager
|
||||
start surfaceflinger
|
||||
```
|
||||
|
||||
### 3.3 关键系统服务启动顺序
|
||||
1. **servicemanager**:Binder IPC服务管理器
|
||||
2. **surfaceflinger**:图形合成服务
|
||||
3. **zygote**:应用进程孵化器
|
||||
4. **system_server**:系统核心服务
|
||||
|
||||
## 4. 调试与优化
|
||||
|
||||
### 4.1 启动时间分析
|
||||
- **bootchart工具**:可视化启动时间分布
|
||||
- **内核日志分析**:`dmesg | grep -i "init"`
|
||||
- **init日志**:`logcat -b events | grep "boot_progress"`
|
||||
|
||||
### 4.2 常见问题排查
|
||||
- **启动卡住**:检查驱动初始化顺序
|
||||
- **服务启动失败**:查看服务依赖关系
|
||||
- **权限问题**:检查SELinux策略
|
||||
|
||||
### 4.3 优化建议
|
||||
- **并行启动**:优化服务启动顺序,减少依赖等待
|
||||
- **延迟加载**:非关键服务延迟到系统启动后加载
|
||||
- **预加载优化**:预加载常用库和资源
|
||||
|
||||
## 5. 实践案例
|
||||
|
||||
### 5.1 自定义启动服务
|
||||
```bash
|
||||
# 在init.rc中添加自定义服务
|
||||
service myservice /system/bin/myservice
|
||||
class main
|
||||
user system
|
||||
group system
|
||||
oneshot
|
||||
```
|
||||
|
||||
### 5.2 启动参数调优
|
||||
- **内核参数**:调整内存分配、调度策略
|
||||
- **init参数**:设置环境变量、调整服务优先级
|
||||
- **系统属性**:配置系统特性开关
|
||||
|
||||
## 总结
|
||||
|
||||
Bootloader到Init是Android系统启动的基础阶段,理解这一过程对于:
|
||||
- **系统定制开发**:修改启动流程满足特定需求
|
||||
- **性能优化**:减少启动时间,提升用户体验
|
||||
- **问题排查**:快速定位启动阶段的问题
|
||||
- **安全加固**:增强启动过程的安全性
|
||||
|
||||
掌握这一阶段的原理和技术细节,是成为高级Android Framework工程师的重要基础。
|
||||
@@ -1,3 +0,0 @@
|
||||
# Launcher启动流程
|
||||
|
||||
Android系统Launcher的完整启动流程分析。
|
||||
@@ -1,171 +0,0 @@
|
||||
# SystemServer核心服务:Android系统服务的基石
|
||||
|
||||
SystemServer是Android系统的核心服务进程,负责启动和管理所有系统级服务。本文详细分析SystemServer的启动流程、核心服务架构和关键实现。
|
||||
|
||||
## SystemServer启动流程概览
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Zygote fork SystemServer] --> B[加载SystemServer类]
|
||||
B --> C[执行main方法]
|
||||
C --> D[初始化系统上下文]
|
||||
D --> E[启动引导服务]
|
||||
E --> F[启动核心服务]
|
||||
F --> G[启动其他服务]
|
||||
G --> H[进入Looper循环]
|
||||
```
|
||||
|
||||
## 1. SystemServer进程创建
|
||||
|
||||
### 1.1 从Zygote孵化
|
||||
- **进程创建**:Zygote通过fork创建SystemServer进程
|
||||
- **资源继承**:继承Zygote预加载的类和资源
|
||||
- **权限设置**:设置系统级权限和用户组
|
||||
|
||||
### 1.2 关键启动代码
|
||||
```java
|
||||
// SystemServer.java
|
||||
public static void main(String[] args) {
|
||||
new SystemServer().run();
|
||||
}
|
||||
|
||||
private void run() {
|
||||
// 1. 初始化系统环境
|
||||
Looper.prepareMainLooper();
|
||||
System.loadLibrary("android_servers");
|
||||
|
||||
// 2. 创建系统上下文
|
||||
createSystemContext();
|
||||
|
||||
// 3. 启动系统服务
|
||||
startBootstrapServices();
|
||||
startCoreServices();
|
||||
startOtherServices();
|
||||
|
||||
// 4. 进入事件循环
|
||||
Looper.loop();
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 引导服务(Bootstrap Services)
|
||||
|
||||
### 2.1 关键引导服务
|
||||
- **Installer**:应用安装服务
|
||||
- **ActivityManagerService**:Activity管理服务
|
||||
- **PowerManagerService**:电源管理服务
|
||||
- **PackageManagerService**:包管理服务
|
||||
- **DisplayManagerService**:显示管理服务
|
||||
|
||||
### 2.2 服务依赖关系
|
||||
```java
|
||||
// 引导服务启动顺序
|
||||
mSystemServiceManager.startService(Installer.class);
|
||||
mActivityManagerService = mSystemServiceManager.startService(
|
||||
ActivityManagerService.Lifecycle.class).getService();
|
||||
mActivityManagerService.setSystemProcess();
|
||||
```
|
||||
|
||||
## 3. 核心服务(Core Services)
|
||||
|
||||
### 3.1 系统核心服务
|
||||
- **BatteryService**:电池服务
|
||||
- **UsageStatsService**:使用统计服务
|
||||
- **WebViewUpdateService**:WebView更新服务
|
||||
- **DropBoxManagerService**:日志收集服务
|
||||
|
||||
### 3.2 关键配置服务
|
||||
- **AlarmManagerService**:闹钟服务
|
||||
- **InputManagerService**:输入管理服务
|
||||
- **WindowManagerService**:窗口管理服务
|
||||
- **VrManagerService**:VR管理服务
|
||||
|
||||
## 4. 其他服务(Other Services)
|
||||
|
||||
### 4.1 系统功能服务
|
||||
- **CameraService**:相机服务
|
||||
- **AudioService**:音频服务
|
||||
- **SensorService**:传感器服务
|
||||
- **BluetoothService**:蓝牙服务
|
||||
|
||||
### 4.2 网络与连接服务
|
||||
- **ConnectivityService**:连接服务
|
||||
- **NsdService**:网络服务发现
|
||||
- **VpnManagerService**:VPN管理服务
|
||||
- **EthernetService**:以太网服务
|
||||
|
||||
## 5. 服务生命周期管理
|
||||
|
||||
### 5.1 服务启动顺序
|
||||
1. **基础服务**:Installer, PowerManager
|
||||
2. **核心框架**:ActivityManager, PackageManager
|
||||
3. **硬件抽象**:DisplayManager, SensorService
|
||||
4. **应用服务**:WindowManager, InputManager
|
||||
|
||||
### 5.2 服务依赖解析
|
||||
- **显式依赖**:通过构造函数参数传递
|
||||
- **隐式依赖**:通过ServiceManager获取
|
||||
- **循环依赖**:使用代理模式解决
|
||||
|
||||
## 6. 性能优化与调试
|
||||
|
||||
### 6.1 启动时间优化
|
||||
- **并行启动**:无依赖服务并行启动
|
||||
- **延迟加载**:非关键服务延迟启动
|
||||
- **预加载优化**:预加载常用资源
|
||||
|
||||
### 6.2 内存管理
|
||||
- **服务内存监控**:监控各服务内存使用
|
||||
- **资源释放**:及时释放未使用资源
|
||||
- **内存泄漏检测**:定期检查内存泄漏
|
||||
|
||||
### 6.3 调试工具
|
||||
```bash
|
||||
# 查看SystemServer日志
|
||||
adb logcat -s SystemServer:I
|
||||
|
||||
# 分析服务启动时间
|
||||
adb shell dumpsys activity service SystemServer
|
||||
|
||||
# 性能分析
|
||||
adb shell systrace.py system_server
|
||||
```
|
||||
|
||||
## 7. 定制化开发
|
||||
|
||||
### 7.1 添加自定义服务
|
||||
```java
|
||||
// 自定义系统服务
|
||||
public class MySystemService extends SystemService {
|
||||
public MySystemService(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
publishBinderService("my_service", new MyServiceImpl());
|
||||
}
|
||||
}
|
||||
|
||||
// 在SystemServer中注册
|
||||
mSystemServiceManager.startService(MySystemService.class);
|
||||
```
|
||||
|
||||
### 7.2 服务配置调整
|
||||
- **启动参数**:调整服务启动参数
|
||||
- **资源限制**:设置服务资源限制
|
||||
- **优先级调整**:调整服务运行优先级
|
||||
|
||||
### 7.3 厂商定制
|
||||
- **硬件适配**:添加硬件特定服务
|
||||
- **功能扩展**:扩展系统功能
|
||||
- **性能调优**:针对特定硬件优化
|
||||
|
||||
## 总结
|
||||
|
||||
SystemServer作为Android系统的服务基石,其设计和实现直接影响:
|
||||
- **系统稳定性**:服务的可靠性和容错能力
|
||||
- **性能表现**:启动时间和运行效率
|
||||
- **功能扩展**:系统功能的可扩展性
|
||||
- **调试维护**:问题的定位和解决效率
|
||||
|
||||
深入理解SystemServer的架构和实现,对于Android Framework工程师进行系统定制、性能优化和问题排查具有重要意义。
|
||||
167
Zygote进程启动.md
167
Zygote进程启动.md
@@ -1,167 +0,0 @@
|
||||
# Zygote进程启动:Android应用进程的孵化器
|
||||
|
||||
Zygote是Android系统的特殊进程,负责孵化(fork)应用进程,实现应用的快速启动和资源共享。本文详细分析Zygote的启动流程、工作原理和优化策略。
|
||||
|
||||
## Zygote启动流程概览
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Init
|
||||
participant Zygote进程
|
||||
participant SystemServer
|
||||
participant App进程
|
||||
|
||||
Init->>Zygote进程: 启动Zygote
|
||||
Zygote进程->>Zygote进程: 预加载类和资源
|
||||
Zygote进程->>SystemServer: fork SystemServer
|
||||
SystemServer->>SystemServer: 启动系统服务
|
||||
Zygote进程->>App进程: fork 应用进程
|
||||
App进程->>App进程: 执行应用代码
|
||||
```
|
||||
|
||||
## 1. Zygote进程创建
|
||||
|
||||
### 1.1 Init启动Zygote
|
||||
- **init.rc配置**:在init.rc中配置Zygote服务
|
||||
- **进程创建**:init进程fork出Zygote进程
|
||||
- **权限设置**:设置Zygote进程权限和资源限制
|
||||
|
||||
### 1.2 Zygote服务配置
|
||||
```bash
|
||||
# init.rc中的Zygote配置
|
||||
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
|
||||
class main
|
||||
socket zygote stream 660 root system
|
||||
onrestart write /sys/android_power/request_state wake
|
||||
onrestart write /sys/power/state on
|
||||
onrestart restart media
|
||||
onrestart restart netd
|
||||
```
|
||||
|
||||
## 2. Zygote初始化
|
||||
|
||||
### 2.1 预加载机制
|
||||
- **类预加载**:预加载常用Java类
|
||||
- **资源预加载**:预加载常用资源
|
||||
- **库预加载**:预加载系统库
|
||||
|
||||
### 2.2 关键初始化代码
|
||||
```java
|
||||
// ZygoteInit.java
|
||||
public static void main(String argv[]) {
|
||||
// 1. 预加载类和资源
|
||||
preload();
|
||||
|
||||
// 2. 启动SystemServer(如果指定)
|
||||
if (argv.length > 1 && argv[1].equals("--start-system-server")) {
|
||||
startSystemServer();
|
||||
}
|
||||
|
||||
// 3. 进入Socket监听循环
|
||||
runSelectLoop();
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 进程孵化机制
|
||||
|
||||
### 3.1 fork流程
|
||||
1. **接收请求**:通过Socket接收进程创建请求
|
||||
2. **参数解析**:解析应用启动参数
|
||||
3. **进程fork**:调用fork系统调用创建新进程
|
||||
4. **子进程初始化**:在新进程中执行应用代码
|
||||
|
||||
### 3.2 关键孵化代码
|
||||
```java
|
||||
// ZygoteConnection.java
|
||||
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors) {
|
||||
// 关闭Zygote的Socket
|
||||
closeSocket();
|
||||
|
||||
// 设置进程名
|
||||
Process.setArgV0(parsedArgs.niceName);
|
||||
|
||||
// 执行应用入口
|
||||
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
|
||||
parsedArgs.remainingArgs, null);
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 资源共享优化
|
||||
|
||||
### 4.1 Copy-on-Write机制
|
||||
- **内存共享**:父子进程共享只读内存页
|
||||
- **写时复制**:修改时复制内存页
|
||||
- **资源复用**:复用预加载的类和资源
|
||||
|
||||
### 4.2 预加载内容
|
||||
- **系统类**:android.*, java.*, javax.* 等
|
||||
- **框架资源**:主题、字符串、图片等
|
||||
- **本地库**:系统so库
|
||||
|
||||
## 5. 性能优化策略
|
||||
|
||||
### 5.1 启动时间优化
|
||||
- **延迟预加载**:非关键类延迟加载
|
||||
- **类过滤**:过滤不常用的类
|
||||
- **并行加载**:并行预加载资源
|
||||
|
||||
### 5.2 内存优化
|
||||
- **内存共享**:最大化内存共享
|
||||
- **资源清理**:及时清理无用资源
|
||||
- **内存监控**:监控Zygote内存使用
|
||||
|
||||
### 5.3 稳定性优化
|
||||
- **进程隔离**:确保进程间隔离
|
||||
- **异常处理**:完善的异常处理机制
|
||||
- **重启恢复**:Zygote崩溃后的恢复
|
||||
|
||||
## 6. 调试与问题排查
|
||||
|
||||
### 6.1 常见问题
|
||||
- **Zygote崩溃**:导致所有应用重启
|
||||
- **内存泄漏**:预加载资源泄漏
|
||||
- **启动失败**:应用进程创建失败
|
||||
|
||||
### 6.2 调试工具
|
||||
```bash
|
||||
# 查看Zygote日志
|
||||
adb logcat -s Zygote:I
|
||||
|
||||
# 分析Zygote内存使用
|
||||
adb shell dumpsys meminfo zygote
|
||||
|
||||
# 跟踪进程创建
|
||||
adb shell strace -p <zygote_pid>
|
||||
```
|
||||
|
||||
### 6.3 性能分析
|
||||
- **启动时间**:分析应用启动时间
|
||||
- **内存占用**:分析内存共享效果
|
||||
- **CPU使用**:分析Zygote CPU使用率
|
||||
|
||||
## 7. 定制化开发
|
||||
|
||||
### 7.1 预加载策略调整
|
||||
- **自定义类**:添加自定义预加载类
|
||||
- **资源优化**:优化预加载资源列表
|
||||
- **库管理**:管理预加载的本地库
|
||||
|
||||
### 7.2 进程管理优化
|
||||
- **进程限制**:调整进程创建限制
|
||||
- **优先级管理**:优化进程优先级
|
||||
- **资源控制**:控制进程资源使用
|
||||
|
||||
### 7.3 厂商定制
|
||||
- **硬件适配**:针对特定硬件优化
|
||||
- **功能扩展**:扩展Zygote功能
|
||||
- **性能调优**:针对特定场景优化
|
||||
|
||||
## 总结
|
||||
|
||||
Zygote作为Android应用进程的孵化器,其设计和实现直接影响:
|
||||
- **应用启动速度**:通过预加载和资源共享加速启动
|
||||
- **系统内存效率**:通过Copy-on-Write减少内存占用
|
||||
- **系统稳定性**:确保进程创建的安全可靠
|
||||
- **系统扩展性**:支持多种应用场景和需求
|
||||
|
||||
深入理解Zygote的工作原理和优化策略,对于Android Framework工程师进行系统性能优化、问题排查和功能扩展具有重要意义。
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1,308 @@
|
||||
# PackageManagerService
|
||||
# PackageManagerService架构
|
||||
|
||||
PackageManagerService(PMS)是Android包管理系统的核心服务,负责应用的安装、卸载、更新和权限管理。本文深入分析PMS的架构设计、工作原理和关键实现。
|
||||
|
||||
## PMS系统架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "客户端层"
|
||||
A1[PackageManager] --> A2[IPackageManager]
|
||||
A2 --> A3[Binder通信]
|
||||
end
|
||||
|
||||
subgraph "服务端层"
|
||||
B1[PackageManagerService] --> B2[PackageParser]
|
||||
B2 --> B3[PackageSettings]
|
||||
B3 --> B4[Installer]
|
||||
|
||||
B1 --> B5[UserManagerService]
|
||||
B1 --> B6[ActivityManagerService]
|
||||
B1 --> B7[StorageManagerService]
|
||||
end
|
||||
|
||||
subgraph "数据层"
|
||||
C1[Package数据库] --> C2[Settings.xml]
|
||||
C2 --> C3[包目录结构]
|
||||
C3 --> C4[APK文件]
|
||||
end
|
||||
|
||||
A3 --> B1
|
||||
B4 --> C4
|
||||
```
|
||||
|
||||
## 1. PMS核心组件
|
||||
|
||||
### 1.1 PackageManagerService
|
||||
- **包管理**:管理所有应用的安装、卸载和更新
|
||||
- **权限管理**:管理应用权限的授予和撤销
|
||||
- **组件管理**:管理Activity、Service等组件信息
|
||||
- **包扫描**:扫描系统和应用目录中的APK文件
|
||||
|
||||
### 1.2 PackageParser
|
||||
- **APK解析**:解析APK文件的AndroidManifest.xml
|
||||
- **组件提取**:提取Activity、Service等组件信息
|
||||
- **资源解析**:解析APK中的资源信息
|
||||
- **签名验证**:验证APK的签名信息
|
||||
|
||||
### 1.3 PackageSettings
|
||||
- **包设置**:存储包的安装信息和设置
|
||||
- **用户管理**:管理多用户下的包状态
|
||||
- **权限状态**:存储权限授予状态
|
||||
- **包状态**:存储包的启用/禁用状态
|
||||
|
||||
## 2. 包安装流程
|
||||
|
||||
### 2.1 安装流程概览
|
||||
```java
|
||||
// PMS安装应用的关键流程
|
||||
public void installPackageAsUser(Uri packageUri, ...) {
|
||||
// 1. 权限检查
|
||||
enforcePermission(...);
|
||||
|
||||
// 2. 创建安装会话
|
||||
int sessionId = createInstallSession(...);
|
||||
|
||||
// 3. 写入APK文件
|
||||
writeApkToSession(sessionId, packageUri);
|
||||
|
||||
// 4. 提交安装
|
||||
commitSession(sessionId);
|
||||
|
||||
// 5. 解析APK
|
||||
PackageParser.Package pkg = parsePackage(...);
|
||||
|
||||
// 6. 验证签名
|
||||
verifySignatures(pkg);
|
||||
|
||||
// 7. 执行安装
|
||||
installPackageTracedLI(pkg, ...);
|
||||
|
||||
// 8. 发送广播
|
||||
sendPackageBroadcast(...);
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 APK解析过程
|
||||
```java
|
||||
// PackageParser解析APK
|
||||
public Package parsePackage(File apkFile, int flags) {
|
||||
// 1. 创建解析器
|
||||
PackageParser parser = new PackageParser();
|
||||
|
||||
// 2. 解析APK
|
||||
Package pkg = parser.parsePackage(apkFile, flags);
|
||||
|
||||
// 3. 收集组件信息
|
||||
collectCertificates(pkg);
|
||||
collectManifestDigest(pkg);
|
||||
|
||||
// 4. 提取四大组件
|
||||
extractActivities(pkg);
|
||||
extractServices(pkg);
|
||||
extractReceivers(pkg);
|
||||
extractProviders(pkg);
|
||||
|
||||
// 5. 提取权限信息
|
||||
extractPermissions(pkg);
|
||||
|
||||
return pkg;
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 包扫描机制
|
||||
|
||||
### 3.1 系统扫描
|
||||
- **系统目录扫描**:扫描/system/app、/system/priv-app等目录
|
||||
- **厂商目录扫描**:扫描/vendor/app等厂商目录
|
||||
- **OEM目录扫描**:扫描/oem/app等OEM目录
|
||||
|
||||
### 3.2 用户数据扫描
|
||||
- **用户安装目录**:扫描/data/app等用户安装目录
|
||||
- **用户数据目录**:扫描/data/user等用户数据目录
|
||||
- **外部存储扫描**:扫描外部存储中的APK文件
|
||||
|
||||
### 3.3 扫描优化
|
||||
```java
|
||||
// PMS包扫描优化策略
|
||||
class PackageManagerService {
|
||||
// 增量扫描:只扫描变化的目录
|
||||
void scanPackagesTracedLI(File scanDir, int scanFlags, ...) {
|
||||
// 1. 检查目录修改时间
|
||||
long lastModified = getLastModifiedTime(scanDir);
|
||||
if (lastModified <= mLastScanTime) {
|
||||
return; // 目录未修改,跳过扫描
|
||||
}
|
||||
|
||||
// 2. 增量扫描
|
||||
List<File> changedFiles = getChangedFiles(scanDir, mLastScanTime);
|
||||
for (File file : changedFiles) {
|
||||
scanPackageTracedLI(file, scanFlags, ...);
|
||||
}
|
||||
|
||||
// 3. 更新扫描时间
|
||||
mLastScanTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// 并行扫描:多线程并行扫描
|
||||
void parallelScanPackages(List<File> scanDirs) {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(4);
|
||||
List<Future<Package>> futures = new ArrayList<>();
|
||||
|
||||
for (File dir : scanDirs) {
|
||||
futures.add(executor.submit(() -> scanPackage(dir)));
|
||||
}
|
||||
|
||||
// 等待所有扫描完成
|
||||
for (Future<Package> future : futures) {
|
||||
Package pkg = future.get();
|
||||
addPackage(pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 权限管理系统
|
||||
|
||||
### 4.1 权限分类
|
||||
- **普通权限**:不影响用户隐私的权限
|
||||
- **危险权限**:涉及用户隐私的权限
|
||||
- **签名权限**:需要相同签名的权限
|
||||
- **特殊权限**:系统特殊权限
|
||||
|
||||
### 4.2 权限授予流程
|
||||
```java
|
||||
// PMS权限授予流程
|
||||
public void grantRuntimePermission(String packageName, String permName, int userId) {
|
||||
// 1. 检查权限是否存在
|
||||
BasePermission bp = mSettings.mPermissions.get(permName);
|
||||
if (bp == null) {
|
||||
throw new SecurityException("Unknown permission: " + permName);
|
||||
}
|
||||
|
||||
// 2. 检查调用者权限
|
||||
enforceGrantRevokeRuntimePermissionPermissions(...);
|
||||
|
||||
// 3. 检查目标应用是否申请该权限
|
||||
PackageParser.Package pkg = getPackage(packageName);
|
||||
if (!pkg.requestedPermissions.contains(permName)) {
|
||||
throw new SecurityException("Package " + packageName + " has not requested permission " + permName);
|
||||
}
|
||||
|
||||
// 4. 授予权限
|
||||
PermissionState permState = mSettings.getPermissionState(permName, packageName, userId);
|
||||
permState.granted = true;
|
||||
permState.grantedFlags = flags;
|
||||
|
||||
// 5. 更新权限状态
|
||||
updatePermissions(packageName, pkg);
|
||||
|
||||
// 6. 发送广播通知
|
||||
sendPackageChangedBroadcast(packageName, userId);
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 多用户支持
|
||||
|
||||
### 5.1 用户隔离
|
||||
- **用户ID**:每个用户有唯一的用户ID
|
||||
- **数据隔离**:不同用户的数据完全隔离
|
||||
- **权限隔离**:不同用户的权限状态独立
|
||||
|
||||
### 5.2 用户管理
|
||||
```java
|
||||
// PMS多用户管理
|
||||
class PackageManagerService {
|
||||
// 用户包状态管理
|
||||
final SparseArray<PackageSetting> mSettingsByUser = new SparseArray<>();
|
||||
|
||||
// 为用户安装包
|
||||
void installPackageAsUser(String packageName, int userId) {
|
||||
// 1. 获取主用户包信息
|
||||
PackageSetting ps = getPackageSetting(packageName, UserHandle.USER_SYSTEM);
|
||||
|
||||
// 2. 为用户创建包状态
|
||||
PackageSetting userPs = createPackageSettingForUser(ps, userId);
|
||||
|
||||
// 3. 设置用户包状态
|
||||
mSettingsByUser.put(userId, userPs);
|
||||
|
||||
// 4. 创建用户数据目录
|
||||
createUserDataIfNeeded(packageName, userId);
|
||||
}
|
||||
|
||||
// 删除用户包
|
||||
void removePackageAsUser(String packageName, int userId) {
|
||||
// 1. 删除用户包状态
|
||||
mSettingsByUser.remove(userId);
|
||||
|
||||
// 2. 删除用户数据目录
|
||||
deleteUserData(packageName, userId);
|
||||
|
||||
// 3. 清理缓存
|
||||
clearPackagePreferredActivities(packageName, userId);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 性能优化
|
||||
|
||||
### 6.1 启动优化
|
||||
- **延迟扫描**:非关键目录延迟扫描
|
||||
- **并行解析**:多APK并行解析
|
||||
- **缓存机制**:缓存已解析的包信息
|
||||
|
||||
### 6.2 内存优化
|
||||
- **对象复用**:复用PackageParser等对象
|
||||
- **懒加载**:按需加载包信息
|
||||
- **资源释放**:及时释放不再使用的资源
|
||||
|
||||
### 6.3 存储优化
|
||||
- **增量更新**:只更新变化的包信息
|
||||
- **压缩存储**:压缩存储包元数据
|
||||
- **索引优化**:优化包查询索引
|
||||
|
||||
## 7. 调试与问题排查
|
||||
|
||||
### 7.1 调试工具
|
||||
```bash
|
||||
# 查看包信息
|
||||
adb shell dumpsys package <package_name>
|
||||
|
||||
# 查看权限信息
|
||||
adb shell dumpsys package permissions
|
||||
|
||||
# 查看安装会话
|
||||
adb shell dumpsys package sessions
|
||||
|
||||
# 查看包管理器状态
|
||||
adb shell dumpsys package
|
||||
|
||||
# 性能分析
|
||||
adb shell dumpsys package --timing
|
||||
```
|
||||
|
||||
### 7.2 常见问题
|
||||
- **安装失败**:签名验证失败、存储空间不足等
|
||||
- **权限问题**:权限未正确授予或撤销
|
||||
- **包冲突**:相同包名或签名的包冲突
|
||||
- **扫描问题**:APK文件损坏或格式错误
|
||||
- **性能问题**:包扫描或解析耗时过长
|
||||
|
||||
### 7.3 问题排查步骤
|
||||
1. **收集日志**:查看logcat中的PMS相关日志
|
||||
2. **检查状态**:使用dumpsys命令检查包状态
|
||||
3. **验证APK**:检查APK文件完整性和签名
|
||||
4. **分析配置**:检查系统配置和权限设置
|
||||
5. **性能分析**:使用性能分析工具定位瓶颈
|
||||
|
||||
## 总结
|
||||
|
||||
PackageManagerService是Android系统的核心服务:
|
||||
- **应用管理**:统一管理所有应用的安装和卸载
|
||||
- **权限控制**:严格控制应用权限的授予和使用
|
||||
- **组件管理**:管理应用组件的注册和发现
|
||||
- **多用户支持**:支持多用户环境下的应用隔离
|
||||
- **系统稳定**:确保应用安装和运行的稳定性
|
||||
|
||||
深入理解PackageManagerService架构,对于优化应用安装体验、排查包管理问题和设计系统级功能具有重要意义。
|
||||
@@ -1 +1,143 @@
|
||||
# 04-资源与包管理
|
||||
# 04-资源与包管理
|
||||
|
||||
本目录包含Android Framework中资源管理与包管理的核心知识和技术文档。资源管理和包管理是Android系统的基础功能,直接影响应用的安装、运行和用户体验。
|
||||
|
||||
## 文档结构
|
||||
|
||||
### 1. 动态加载与热修复原理.md
|
||||
- **内容**:深入分析Android动态加载和热修复技术的原理与实现
|
||||
- **重点**:插件化架构、热修复方案、资源合并、So库修复
|
||||
- **适用**:需要实现应用热更新和插件化架构的开发者
|
||||
|
||||
### 2. PackageManagerService.md
|
||||
- **内容**:全面分析PackageManagerService的架构设计和工作原理
|
||||
- **重点**:包安装流程、权限管理、包扫描机制、多用户支持
|
||||
- **适用**:需要深入理解Android包管理机制的开发者
|
||||
|
||||
### 3. Resource资源加载机制.md
|
||||
- **内容**:详细分析Android资源系统的加载机制和优化策略
|
||||
- **重点**:资源编译、资源查找、资源缓存、多语言支持
|
||||
- **适用**:需要优化资源加载性能和实现动态换肤的开发者
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 资源管理系统
|
||||
- **资源编译**:aapt2将资源编译为二进制格式
|
||||
- **资源打包**:资源打包到APK的resources.arsc
|
||||
- **资源查找**:通过Resource ID查找对应资源
|
||||
- **资源缓存**:缓存已加载的资源提高性能
|
||||
|
||||
### 包管理系统
|
||||
- **APK结构**:Dex文件、资源文件、Native库、清单文件
|
||||
- **包安装**:验证、解析、复制、优化、注册
|
||||
- **权限管理**:权限分类、授予、检查、撤销
|
||||
- **组件管理**:Activity、Service、Receiver、Provider注册
|
||||
|
||||
### 动态加载系统
|
||||
- **类加载**:DexClassLoader、PathClassLoader
|
||||
- **资源合并**:AssetManager多路径加载
|
||||
- **热修复**:方法替换、类替换、资源替换
|
||||
- **插件化**:插件生命周期、组件代理、通信机制
|
||||
|
||||
## 技术要点
|
||||
|
||||
### 1. 性能优化
|
||||
- **资源优化**:减少资源大小、使用WebP格式、资源压缩
|
||||
- **包优化**:减少APK大小、使用App Bundle、动态交付
|
||||
- **加载优化**:懒加载、预加载、缓存策略
|
||||
|
||||
### 2. 安全考虑
|
||||
- **签名验证**:验证APK签名防止篡改
|
||||
- **权限控制**:最小权限原则、运行时权限
|
||||
- **代码保护**:代码混淆、资源加密、反调试
|
||||
|
||||
### 3. 兼容性处理
|
||||
- **版本适配**:处理不同Android版本的API差异
|
||||
- **厂商适配**:处理各厂商的系统定制问题
|
||||
- **架构适配**:支持不同CPU架构和屏幕密度
|
||||
|
||||
## 调试工具
|
||||
|
||||
### 常用命令
|
||||
```bash
|
||||
# 查看包信息
|
||||
adb shell dumpsys package <package_name>
|
||||
adb shell pm list packages
|
||||
adb shell pm path <package_name>
|
||||
|
||||
# 查看资源信息
|
||||
adb shell dumpsys resources
|
||||
adb shell getprop | grep density
|
||||
adb shell wm size
|
||||
|
||||
# 查看安装信息
|
||||
adb shell dumpsys package installs
|
||||
adb shell dumpsys package sessions
|
||||
|
||||
# 性能分析
|
||||
adb shell dumpsys package --timing
|
||||
adb shell am profile start <process> <trace_file>
|
||||
```
|
||||
|
||||
### 开发者工具
|
||||
- **Android Studio Profiler**:分析资源使用和性能
|
||||
- **Layout Inspector**:查看界面布局和资源
|
||||
- **APK Analyzer**:分析APK结构和资源
|
||||
- **Systrace/Perfetto**:性能跟踪和分析
|
||||
|
||||
## 学习路径
|
||||
|
||||
### 初级开发者
|
||||
1. 理解Android资源系统和包管理基本概念
|
||||
2. 掌握资源使用和权限申请
|
||||
3. 学会基本的APK分析和优化
|
||||
|
||||
### 中级开发者
|
||||
1. 深入理解PackageManagerService架构
|
||||
2. 掌握资源加载和热修复原理
|
||||
3. 学会插件化架构设计和实现
|
||||
|
||||
### 高级开发者
|
||||
1. 理解系统底层资源管理和包管理机制
|
||||
2. 掌握性能优化和安全加固技术
|
||||
3. 能够设计和实现复杂的动态加载系统
|
||||
|
||||
## 相关资源
|
||||
|
||||
### 官方文档
|
||||
- [Android Developers - App Resources](https://developer.android.com/guide/topics/resources)
|
||||
- [Android Developers - App Manifest](https://developer.android.com/guide/topics/manifest)
|
||||
- [Android Developers - Permissions](https://developer.android.com/guide/topics/permissions)
|
||||
- [Android Developers - Dynamic Delivery](https://developer.android.com/guide/app-bundle)
|
||||
|
||||
### 开源项目
|
||||
- [Android Open Source Project - PackageManagerService](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/core/java/com/android/server/pm/)
|
||||
- [Android Open Source Project - Resource Manager](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/res/)
|
||||
- [Tinker - 热修复框架](https://github.com/Tencent/tinker)
|
||||
- [VirtualAPK - 插件化框架](https://github.com/didi/VirtualAPK)
|
||||
|
||||
### 工具资源
|
||||
- [Android Asset Packaging Tool 2 (aapt2)](https://developer.android.com/studio/command-line/aapt2)
|
||||
- [APK Analyzer](https://developer.android.com/studio/build/apk-analyzer)
|
||||
- [Bundletool](https://developer.android.com/studio/command-line/bundletool)
|
||||
- [AndResGuard - 资源混淆工具](https://github.com/shwenzhang/AndResGuard)
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2026-01-12
|
||||
- 完善所有文档内容,使用标准Markdown格式
|
||||
- 添加详细的技术分析和最佳实践
|
||||
- 补充调试工具和问题排查方法
|
||||
- 更新相关资源和学习路径
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎对本目录的文档进行改进和补充:
|
||||
1. 确保内容准确、技术正确,反映最新Android版本特性
|
||||
2. 使用标准的Markdown格式,保持文档结构清晰
|
||||
3. 添加实际代码示例和最佳实践,便于读者理解
|
||||
4. 保持文档的实用性和可读性,避免过于理论化
|
||||
|
||||
---
|
||||
|
||||
*本目录文档将持续更新,以反映Android Framework的最新发展和最佳实践。*
|
||||
@@ -1 +1,370 @@
|
||||
# Resource资源加载机制
|
||||
# Resource资源加载机制
|
||||
|
||||
Android资源系统是应用界面和功能的基础,负责管理字符串、图片、布局等所有资源。本文深入分析Android资源系统的加载机制、优化策略和最佳实践。
|
||||
|
||||
## 资源系统架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "编译阶段"
|
||||
A1[资源文件] --> A2[aapt2编译]
|
||||
A2 --> A3[resources.arsc]
|
||||
A3 --> A4[APK包]
|
||||
end
|
||||
|
||||
subgraph "运行阶段"
|
||||
B1[APK包] --> B2[AssetManager]
|
||||
B2 --> B3[Resources]
|
||||
B3 --> B4[ResourceTable]
|
||||
|
||||
B2 --> B5[资源缓存]
|
||||
B3 --> B6[Configuration]
|
||||
B4 --> B7[资源查找]
|
||||
end
|
||||
|
||||
subgraph "应用层"
|
||||
C1[Activity] --> C2[getResources]
|
||||
C2 --> C3[资源访问]
|
||||
C3 --> C4[界面渲染]
|
||||
end
|
||||
|
||||
A4 --> B1
|
||||
B7 --> C3
|
||||
```
|
||||
|
||||
## 1. 资源编译与打包
|
||||
|
||||
### 1.1 资源编译流程
|
||||
- **aapt2编译**:将XML和图片资源编译为二进制格式
|
||||
- **资源链接**:将所有资源链接到resources.arsc
|
||||
- **资源优化**:优化资源大小和加载效率
|
||||
|
||||
### 1.2 resources.arsc结构
|
||||
```cpp
|
||||
// resources.arsc文件结构
|
||||
struct ResTable_header {
|
||||
struct ResChunk_header header; // 块头信息
|
||||
uint32_t packageCount; // 包数量
|
||||
};
|
||||
|
||||
struct ResTable_package {
|
||||
struct ResChunk_header header; // 包头信息
|
||||
uint32_t id; // 包ID
|
||||
char16_t name[128]; // 包名
|
||||
uint32_t typeStrings; // 类型字符串偏移
|
||||
uint32_t lastPublicType; // 最后公共类型
|
||||
uint32_t keyStrings; // 键字符串偏移
|
||||
uint32_t lastPublicKey; // 最后公共键
|
||||
uint32_t typeIdOffset; // 类型ID偏移
|
||||
};
|
||||
```
|
||||
|
||||
### 1.3 资源ID结构
|
||||
```
|
||||
0xPPTTEEEE
|
||||
PP (1字节): Package ID (0x01: 系统资源, 0x7F: 应用资源)
|
||||
TT (1字节): Type ID (资源类型: 0x01: anim, 0x02: attr等)
|
||||
EEEE (2字节): Entry ID (资源条目ID)
|
||||
```
|
||||
|
||||
## 2. 资源加载机制
|
||||
|
||||
### 2.1 AssetManager初始化
|
||||
```java
|
||||
// AssetManager初始化流程
|
||||
public AssetManager() {
|
||||
// 1. 创建Native对象
|
||||
mObject = nativeCreate();
|
||||
|
||||
// 2. 添加资源路径
|
||||
addAssetPath(getPackageResourcePath());
|
||||
|
||||
// 3. 确保资源表已加载
|
||||
ensureStringBlocks();
|
||||
}
|
||||
|
||||
// 添加资源路径
|
||||
public int addAssetPath(String path) {
|
||||
synchronized (this) {
|
||||
// 调用Native方法添加资源路径
|
||||
int res = addAssetPathNative(path);
|
||||
makeStringBlocks(mStringBlocks);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 Resources创建
|
||||
```java
|
||||
// Resources创建流程
|
||||
public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
|
||||
mAssets = assets;
|
||||
mMetrics = metrics;
|
||||
mConfiguration = config;
|
||||
|
||||
// 更新配置
|
||||
updateConfiguration(config, metrics);
|
||||
|
||||
// 创建兼容性信息
|
||||
mCompatibilityInfo = compatibilityInfo;
|
||||
|
||||
// 初始化资源实现
|
||||
mResourcesImpl = new ResourcesImpl(assets, metrics, config, compatibilityInfo);
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 资源查找流程
|
||||
|
||||
### 3.1 资源查找算法
|
||||
```cpp
|
||||
// Native层资源查找
|
||||
status_t AssetManager::getResourceValue(
|
||||
uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density) {
|
||||
// 1. 解析资源ID
|
||||
const uint32_t packageId = getPackageId(resID);
|
||||
const uint32_t typeId = getTypeId(resID);
|
||||
const uint32_t entryId = getEntryId(resID);
|
||||
|
||||
// 2. 查找包
|
||||
const Package* package = getPackage(packageId);
|
||||
if (package == NULL) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
// 3. 查找类型
|
||||
const Type* type = package->getType(typeId, density);
|
||||
if (type == NULL) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
// 4. 查找条目
|
||||
const Entry* entry = type->getEntry(entryId);
|
||||
if (entry == NULL) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
// 5. 返回值
|
||||
*outValue = entry->getValue();
|
||||
return NO_ERROR;
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 资源缓存机制
|
||||
```java
|
||||
// Resources中的资源缓存
|
||||
class Resources {
|
||||
// 资源缓存
|
||||
private final LongSparseArray<Drawable.ConstantState> mDrawableCache;
|
||||
private final LongSparseArray<ColorStateList> mColorStateListCache;
|
||||
private final LongSparseArray<ComplexColor> mComplexColorCache;
|
||||
|
||||
// 获取Drawable(带缓存)
|
||||
public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme) {
|
||||
// 1. 检查缓存
|
||||
final long key = (((long) theme) << 32) | ((long) id);
|
||||
Drawable.ConstantState cs = mDrawableCache.get(key);
|
||||
if (cs != null) {
|
||||
return cs.newDrawable(this);
|
||||
}
|
||||
|
||||
// 2. 加载资源
|
||||
TypedValue value = new TypedValue();
|
||||
getValue(id, value, true);
|
||||
|
||||
// 3. 创建Drawable
|
||||
Drawable dr = loadDrawable(value, id, theme);
|
||||
|
||||
// 4. 放入缓存
|
||||
if (dr != null && dr.getConstantState() != null) {
|
||||
mDrawableCache.put(key, dr.getConstantState());
|
||||
}
|
||||
|
||||
return dr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 多配置支持
|
||||
|
||||
### 4.1 配置限定符
|
||||
- **语言区域**:zh、en、fr等
|
||||
- **屏幕方向**:port、land
|
||||
- **屏幕密度**:ldpi、mdpi、hdpi、xhdpi等
|
||||
- **屏幕尺寸**:small、normal、large、xlarge
|
||||
- **API级别**:v21、v23等
|
||||
|
||||
### 4.2 配置匹配算法
|
||||
```java
|
||||
// 配置匹配算法
|
||||
public Configuration findBestConfig(Configuration config, Configuration[] configs) {
|
||||
Configuration bestConfig = null;
|
||||
int bestScore = Integer.MIN_VALUE;
|
||||
|
||||
for (Configuration candidate : configs) {
|
||||
// 计算匹配分数
|
||||
int score = config.match(candidate);
|
||||
|
||||
// 选择最高分
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
bestConfig = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return bestConfig;
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 动态资源加载
|
||||
|
||||
### 5.1 皮肤切换
|
||||
```java
|
||||
// 动态换肤实现
|
||||
public class SkinManager {
|
||||
private AssetManager mAssetManager;
|
||||
private Resources mResources;
|
||||
private String mSkinPath;
|
||||
|
||||
// 加载皮肤
|
||||
public void loadSkin(String skinPath) {
|
||||
try {
|
||||
// 1. 创建新的AssetManager
|
||||
mAssetManager = AssetManager.class.newInstance();
|
||||
|
||||
// 2. 添加皮肤资源路径
|
||||
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
|
||||
addAssetPath.invoke(mAssetManager, skinPath);
|
||||
|
||||
// 3. 创建新的Resources
|
||||
Resources superRes = getResources();
|
||||
mResources = new Resources(mAssetManager,
|
||||
superRes.getDisplayMetrics(),
|
||||
superRes.getConfiguration());
|
||||
|
||||
mSkinPath = skinPath;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取皮肤资源
|
||||
public Resources getSkinResources() {
|
||||
return mResources;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 插件资源合并
|
||||
```java
|
||||
// 插件资源合并
|
||||
public class PluginResourceManager {
|
||||
private AssetManager mHostAssetManager;
|
||||
private List<AssetManager> mPluginAssetManagers = new ArrayList<>();
|
||||
|
||||
// 合并插件资源
|
||||
public void mergePluginResources(String pluginApkPath) {
|
||||
try {
|
||||
// 1. 创建插件AssetManager
|
||||
AssetManager pluginAssetManager = AssetManager.class.newInstance();
|
||||
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
|
||||
addAssetPath.invoke(pluginAssetManager, pluginApkPath);
|
||||
|
||||
// 2. 添加到列表
|
||||
mPluginAssetManagers.add(pluginAssetManager);
|
||||
|
||||
// 3. 创建合并的Resources
|
||||
Resources mergedResources = createMergedResources();
|
||||
|
||||
// 4. 更新应用Resources
|
||||
updateApplicationResources(mergedResources);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 创建合并的Resources
|
||||
private Resources createMergedResources() {
|
||||
// 合并所有AssetManager的资源
|
||||
// 注意:需要处理资源ID冲突
|
||||
return new MergedResources(mHostAssetManager, mPluginAssetManagers);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 性能优化
|
||||
|
||||
### 6.1 资源优化策略
|
||||
- **资源压缩**:使用WebP格式、压缩PNG
|
||||
- **资源分包**:按需加载资源包
|
||||
- **资源缓存**:合理设置缓存大小和策略
|
||||
- **懒加载**:按需加载大资源
|
||||
|
||||
### 6.2 内存优化
|
||||
```java
|
||||
// 资源内存优化
|
||||
class ResourceMemoryOptimizer {
|
||||
// 监控资源内存使用
|
||||
public void monitorResourceMemory() {
|
||||
// 1. 获取当前内存状态
|
||||
Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
|
||||
Debug.getMemoryInfo(memoryInfo);
|
||||
|
||||
// 2. 检查资源缓存大小
|
||||
long drawableCacheSize = calculateDrawableCacheSize();
|
||||
long colorCacheSize = calculateColorCacheSize();
|
||||
|
||||
// 3. 根据内存压力调整缓存
|
||||
if (memoryInfo.getTotalPss() > MEMORY_THRESHOLD) {
|
||||
clearUnusedResources();
|
||||
shrinkResourceCaches();
|
||||
}
|
||||
}
|
||||
|
||||
// 清理未使用资源
|
||||
private void clearUnusedResources() {
|
||||
// 清理长时间未使用的资源
|
||||
// 根据LRU算法清理缓存
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 调试与问题排查
|
||||
|
||||
### 7.1 调试工具
|
||||
```bash
|
||||
# 查看资源信息
|
||||
adb shell dumpsys resources
|
||||
adb shell dumpsys meminfo <package_name> | grep -A 10 "Asset Allocations"
|
||||
|
||||
# 查看当前配置
|
||||
adb shell getprop | grep -E "(density|locale|orientation)"
|
||||
adb shell wm size
|
||||
adb shell wm density
|
||||
|
||||
# 性能分析
|
||||
adb shell am dumpheap <process> <heap_file>
|
||||
adb shell am profile start <process> <trace_file>
|
||||
```
|
||||
|
||||
### 7.2 常见问题
|
||||
- **资源找不到**:资源ID错误、资源未编译、配置不匹配
|
||||
- **内存泄漏**:资源未正确释放、缓存过大
|
||||
- **性能问题**:资源加载过慢、缓存命中率低
|
||||
- **兼容性问题**:不同设备配置资源不匹配
|
||||
|
||||
### 7.3 问题排查步骤
|
||||
1. **检查资源ID**:确认资源ID是否正确
|
||||
2. **检查资源配置**:确认设备配置和资源匹配
|
||||
3. **检查资源文件**:确认资源文件存在且格式正确
|
||||
4. **分析内存使用**:检查资源内存占用情况
|
||||
5. **性能分析**:使用性能分析工具定位瓶颈
|
||||
|
||||
## 总结
|
||||
|
||||
Android资源系统是应用开发的基础:
|
||||
- **高效加载**:二进制格式和缓存机制确保高效加载
|
||||
- **灵活配置**:多配置支持适应不同设备和场景
|
||||
- **动态扩展**:支持皮肤切换和插件资源合并
|
||||
- **性能优化**:多种优化策略确保良好性能
|
||||
|
||||
深入理解Resource资源加载机制,对于优化应用性能、实现动态换肤和设计插件化架构具有重要意义。
|
||||
@@ -1 +1,249 @@
|
||||
# 动态加载与热修复原理
|
||||
# 动态加载与热修复原理
|
||||
|
||||
Android动态加载和热修复技术允许应用在不重新安装的情况下更新代码和资源,提升用户体验和开发效率。本文深入分析动态加载和热修复的核心原理、实现方案和最佳实践。
|
||||
|
||||
## 技术架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "动态加载"
|
||||
A1[宿主应用] --> A2[DexClassLoader]
|
||||
A2 --> A3[插件APK]
|
||||
A3 --> A4[插件资源]
|
||||
A4 --> A5[插件Activity]
|
||||
end
|
||||
|
||||
subgraph "热修复"
|
||||
B1[原始类] --> B2[补丁类]
|
||||
B2 --> B3[类加载替换]
|
||||
B3 --> B4[方法替换]
|
||||
B4 --> B5[即时生效]
|
||||
end
|
||||
|
||||
subgraph "资源管理"
|
||||
C1[AssetManager] --> C2[资源合并]
|
||||
C2 --> C3[资源重定向]
|
||||
C3 --> C4[资源隔离]
|
||||
end
|
||||
```
|
||||
|
||||
## 1. 动态加载技术
|
||||
|
||||
### 1.1 类加载机制
|
||||
- **双亲委派模型**:ClassLoader的类加载机制
|
||||
- **DexClassLoader**:支持从APK/JAR文件加载Dex
|
||||
- **PathClassLoader**:系统默认的ClassLoader
|
||||
|
||||
### 1.2 插件化架构
|
||||
```java
|
||||
// 插件化核心代码示例
|
||||
public class PluginManager {
|
||||
private DexClassLoader mClassLoader;
|
||||
private AssetManager mAssetManager;
|
||||
private Resources mResources;
|
||||
|
||||
// 加载插件
|
||||
public void loadPlugin(String apkPath) {
|
||||
// 1. 创建DexClassLoader
|
||||
mClassLoader = new DexClassLoader(
|
||||
apkPath, // APK路径
|
||||
getDir("dex", 0).getPath(), // 优化后的Dex输出目录
|
||||
null, // 库文件目录
|
||||
getClassLoader() // 父ClassLoader
|
||||
);
|
||||
|
||||
// 2. 创建AssetManager加载插件资源
|
||||
mAssetManager = AssetManager.class.newInstance();
|
||||
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
|
||||
addAssetPath.invoke(mAssetManager, apkPath);
|
||||
|
||||
// 3. 创建Resources对象
|
||||
Resources superRes = getResources();
|
||||
mResources = new Resources(mAssetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
|
||||
}
|
||||
|
||||
// 加载插件类
|
||||
public Class<?> loadClass(String className) throws ClassNotFoundException {
|
||||
return mClassLoader.loadClass(className);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 热修复技术
|
||||
|
||||
### 2.1 热修复原理
|
||||
- **方法替换**:运行时替换有问题的Java方法
|
||||
- **类加载替换**:替换ClassLoader加载的类
|
||||
- **Native修复**:修复Native层的代码问题
|
||||
|
||||
### 2.2 主流方案对比
|
||||
|
||||
| 方案 | 原理 | 优点 | 缺点 |
|
||||
|------|------|------|------|
|
||||
| **AndFix** | Native方法替换 | 即时生效,兼容性好 | 需要适配不同Android版本 |
|
||||
| **Tinker** | 全量Dex替换 | 修复彻底,支持资源修复 | 需要重启应用 |
|
||||
| **Sophix** | 混合模式 | 即时生效+全量替换 | 商业方案,需要付费 |
|
||||
| **Robust** | Instant Run原理 | 稳定性高 | 方法插桩,包体积增大 |
|
||||
|
||||
### 2.3 Tinker实现原理
|
||||
```java
|
||||
// Tinker核心原理:Dex差分合并
|
||||
public class TinkerManager {
|
||||
// 1. 生成差分包
|
||||
public void generatePatch(String oldApk, String newApk, String patchPath) {
|
||||
// 使用BSDiff算法生成Dex差分
|
||||
BsDiff.diff(oldApk, newApk, patchPath);
|
||||
}
|
||||
|
||||
// 2. 应用补丁
|
||||
public void applyPatch(Context context, String patchPath) {
|
||||
// 加载补丁Dex
|
||||
DexClassLoader patchClassLoader = new DexClassLoader(
|
||||
patchPath,
|
||||
context.getDir("patch", 0).getPath(),
|
||||
null,
|
||||
PathClassLoader.getSystemClassLoader()
|
||||
);
|
||||
|
||||
// 合并到主DexClassLoader
|
||||
mergeDexElements(patchClassLoader, context.getClassLoader());
|
||||
}
|
||||
|
||||
// 3. 合并DexElements
|
||||
private void mergeDexElements(ClassLoader patchLoader, ClassLoader mainLoader) {
|
||||
// 通过反射合并DexPathList中的dexElements数组
|
||||
// 将补丁Dex插入到数组最前面,优先加载
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 资源热修复
|
||||
|
||||
### 3.1 资源加载机制
|
||||
- **AssetManager**:Android资源管理核心类
|
||||
- **Resources**:资源访问接口
|
||||
- **ResourceTable**:资源ID映射表
|
||||
|
||||
### 3.2 资源合并方案
|
||||
```java
|
||||
// 资源合并实现
|
||||
public class ResourceManager {
|
||||
private AssetManager mAssetManager;
|
||||
private Resources mResources;
|
||||
|
||||
// 合并插件资源
|
||||
public void mergeResources(String pluginApkPath) {
|
||||
try {
|
||||
// 1. 创建新的AssetManager
|
||||
mAssetManager = AssetManager.class.newInstance();
|
||||
|
||||
// 2. 添加宿主资源路径
|
||||
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
|
||||
addAssetPath.invoke(mAssetManager, getPackageResourcePath());
|
||||
|
||||
// 3. 添加插件资源路径
|
||||
addAssetPath.invoke(mAssetManager, pluginApkPath);
|
||||
|
||||
// 4. 创建新的Resources
|
||||
Resources superRes = getResources();
|
||||
mResources = new Resources(mAssetManager,
|
||||
superRes.getDisplayMetrics(),
|
||||
superRes.getConfiguration());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取合并后的资源
|
||||
public Resources getResources() {
|
||||
return mResources;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. So库热修复
|
||||
|
||||
### 4.1 So库加载机制
|
||||
- **System.loadLibrary**:加载系统库
|
||||
- **System.load**:加载指定路径的库
|
||||
- **NativeLoader**:Android系统的Native加载器
|
||||
|
||||
### 4.2 So库替换方案
|
||||
```java
|
||||
// So库热修复实现
|
||||
public class SoHotFix {
|
||||
// 加载补丁So库
|
||||
public static void loadPatchSo(String soPath) {
|
||||
try {
|
||||
// 1. 获取系统的NativeLibrary路径
|
||||
Field libraryPathField = ClassLoader.class.getDeclaredField("libraryPath");
|
||||
libraryPathField.setAccessible(true);
|
||||
|
||||
// 2. 添加补丁So库路径
|
||||
String oldPath = (String) libraryPathField.get(ClassLoader.getSystemClassLoader());
|
||||
String newPath = soPath + File.pathSeparator + oldPath;
|
||||
libraryPathField.set(ClassLoader.getSystemClassLoader(), newPath);
|
||||
|
||||
// 3. 重新加载So库
|
||||
System.loadLibrary("patched_lib");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 性能与兼容性
|
||||
|
||||
### 5.1 性能优化
|
||||
- **懒加载**:按需加载插件组件
|
||||
- **缓存机制**:缓存已加载的类和资源
|
||||
- **预加载**:提前加载常用插件
|
||||
|
||||
### 5.2 兼容性处理
|
||||
- **API适配**:处理不同Android版本的API差异
|
||||
- **厂商适配**:处理各厂商的系统定制问题
|
||||
- **架构适配**:支持ARM、x86等不同CPU架构
|
||||
|
||||
## 6. 安全考虑
|
||||
|
||||
### 6.1 安全风险
|
||||
- **代码注入**:恶意插件注入危险代码
|
||||
- **资源劫持**:插件劫持宿主资源
|
||||
- **数据泄露**:插件访问敏感数据
|
||||
|
||||
### 6.2 安全措施
|
||||
- **签名验证**:验证插件签名合法性
|
||||
- **权限控制**:限制插件权限范围
|
||||
- **沙箱隔离**:插件运行在隔离环境
|
||||
|
||||
## 7. 调试与问题排查
|
||||
|
||||
### 7.1 调试工具
|
||||
```bash
|
||||
# 查看ClassLoader信息
|
||||
adb shell dumpsys activity top | grep -A 20 "ClassLoader"
|
||||
|
||||
# 查看Dex文件信息
|
||||
adb shell dex2oat --dex-file=<dex_path> --oat-file=<oat_path>
|
||||
|
||||
# 性能分析
|
||||
adb shell am profile start <process> <trace_file>
|
||||
adb shell am profile stop <process>
|
||||
```
|
||||
|
||||
### 7.2 常见问题
|
||||
- **类找不到**:ClassLoader加载路径问题
|
||||
- **资源冲突**:资源ID重复或冲突
|
||||
- **内存泄漏**:插件未正确释放资源
|
||||
- **兼容性问题**:特定机型或系统版本问题
|
||||
|
||||
## 总结
|
||||
|
||||
动态加载与热修复是Android高级开发的重要技术:
|
||||
- **灵活更新**:实现应用的不重启更新
|
||||
- **快速修复**:及时修复线上问题
|
||||
- **模块化开发**:支持插件化架构
|
||||
- **用户体验**:提升用户使用体验
|
||||
|
||||
深入理解动态加载与热修复原理,对于构建稳定、可维护的Android应用具有重要意义。
|
||||
@@ -1 +1,555 @@
|
||||
# AIDL与HIDL使用与原理
|
||||
|
||||
在Android系统中,AIDL(Android Interface Definition Language)和HIDL(Hardware Interface Definition Language)是两种重要的跨进程通信机制。本文深入分析它们的原理、使用方法和最佳实践。
|
||||
|
||||
## 架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "AIDL架构"
|
||||
A1[客户端 Client] --> A2[代理 Proxy]
|
||||
A2 --> A3[服务端 Service]
|
||||
A3 --> A4[Binder驱动]
|
||||
A4 --> A5[系统服务]
|
||||
end
|
||||
|
||||
subgraph "HIDL架构"
|
||||
B1[HAL层] --> B2[HIDL接口]
|
||||
B2 --> B3[Framework层]
|
||||
B3 --> B4[应用层]
|
||||
B4 --> B5[硬件抽象]
|
||||
end
|
||||
|
||||
subgraph "通信流程"
|
||||
C1[接口定义] --> C2[代码生成]
|
||||
C2 --> C3[服务实现]
|
||||
C3 --> C4[客户端调用]
|
||||
C4 --> C5[数据传输]
|
||||
end
|
||||
```
|
||||
|
||||
## 1. AIDL基础
|
||||
|
||||
### 1.1 AIDL接口定义
|
||||
```java
|
||||
// IBookManager.aidl
|
||||
package com.example.aidl;
|
||||
|
||||
// 导入其他AIDL接口
|
||||
import com.example.aidl.IBookListener;
|
||||
|
||||
// 定义接口
|
||||
interface IBookManager {
|
||||
// 基本数据类型
|
||||
int getBookCount();
|
||||
|
||||
// 自定义对象(需要实现Parcelable)
|
||||
Book getBook(in int bookId);
|
||||
|
||||
// 对象列表
|
||||
List<Book> getBookList();
|
||||
|
||||
// 添加书籍
|
||||
void addBook(in Book book);
|
||||
|
||||
// 注册监听器(oneway表示异步调用)
|
||||
oneway void registerListener(IBookListener listener);
|
||||
|
||||
// 注销监听器
|
||||
oneway void unregisterListener(IBookListener listener);
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 Parcelable对象定义
|
||||
```java
|
||||
// Book.java - 实现Parcelable接口
|
||||
public class Book implements Parcelable {
|
||||
private int id;
|
||||
private String name;
|
||||
private double price;
|
||||
|
||||
// Parcelable实现
|
||||
protected Book(Parcel in) {
|
||||
id = in.readInt();
|
||||
name = in.readString();
|
||||
price = in.readDouble();
|
||||
}
|
||||
|
||||
public static final Creator<Book> CREATOR = new Creator<Book>() {
|
||||
@Override
|
||||
public Book createFromParcel(Parcel in) {
|
||||
return new Book(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Book[] newArray(int size) {
|
||||
return new Book[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(id);
|
||||
dest.writeString(name);
|
||||
dest.writeDouble(price);
|
||||
}
|
||||
|
||||
// 对应Book.aidl文件
|
||||
// parcelable Book;
|
||||
}
|
||||
```
|
||||
|
||||
## 2. AIDL服务实现
|
||||
|
||||
### 2.1 服务端实现
|
||||
```java
|
||||
// BookManagerService.java
|
||||
public class BookManagerService extends Service {
|
||||
private static final String TAG = "BookManagerService";
|
||||
|
||||
// 线程安全的书籍列表
|
||||
private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
|
||||
|
||||
// 监听器列表
|
||||
private CopyOnWriteArrayList<IBookListener> mListenerList =
|
||||
new CopyOnWriteArrayList<>();
|
||||
|
||||
// 死亡监听器
|
||||
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
// 客户端进程死亡处理
|
||||
Log.w(TAG, "binder died");
|
||||
}
|
||||
};
|
||||
|
||||
// Binder实现
|
||||
private Binder mBinder = new IBookManager.Stub() {
|
||||
@Override
|
||||
public int getBookCount() {
|
||||
return mBookList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Book getBook(int bookId) {
|
||||
for (Book book : mBookList) {
|
||||
if (book.getId() == bookId) {
|
||||
return book;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> getBookList() {
|
||||
return mBookList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBook(Book book) {
|
||||
mBookList.add(book);
|
||||
// 通知所有监听器
|
||||
for (IBookListener listener : mListenerList) {
|
||||
try {
|
||||
listener.onNewBookArrived(book);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListener(IBookListener listener) {
|
||||
if (!mListenerList.contains(listener)) {
|
||||
mListenerList.add(listener);
|
||||
try {
|
||||
listener.asBinder().linkToDeath(mDeathRecipient, 0);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterListener(IBookListener listener) {
|
||||
mListenerList.remove(listener);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// 初始化数据
|
||||
mBookList.add(new Book(1, "Android开发艺术探索", 79.0));
|
||||
mBookList.add(new Book(2, "深入理解Android内核设计", 89.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 客户端调用
|
||||
```java
|
||||
// MainActivity.java
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
private IBookManager mBookManager;
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mBookManager = IBookManager.Stub.asInterface(service);
|
||||
try {
|
||||
// 连接死亡监听
|
||||
service.linkToDeath(mDeathRecipient, 0);
|
||||
|
||||
// 调用远程方法
|
||||
int count = mBookManager.getBookCount();
|
||||
Log.d(TAG, "Book count: " + count);
|
||||
|
||||
// 获取书籍列表
|
||||
List<Book> bookList = mBookManager.getBookList();
|
||||
for (Book book : bookList) {
|
||||
Log.d(TAG, "Book: " + book.getName());
|
||||
}
|
||||
|
||||
// 注册监听器
|
||||
mBookManager.registerListener(mBookListener);
|
||||
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mBookManager = null;
|
||||
}
|
||||
};
|
||||
|
||||
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
// 重新绑定服务
|
||||
if (mBookManager != null) {
|
||||
mBookManager.asBinder().unlinkToDeath(mDeathRecipient, 0);
|
||||
mBookManager = null;
|
||||
}
|
||||
bindService();
|
||||
}
|
||||
};
|
||||
|
||||
private IBookListener mBookListener = new IBookListener.Stub() {
|
||||
@Override
|
||||
public void onNewBookArrived(Book newBook) {
|
||||
// 注意:这里运行在Binder线程池中
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(MainActivity.this,
|
||||
"New book: " + newBook.getName(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private void bindService() {
|
||||
Intent intent = new Intent(this, BookManagerService.class);
|
||||
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
bindService();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (mBookManager != null && mBookManager.asBinder().isBinderAlive()) {
|
||||
try {
|
||||
mBookManager.unregisterListener(mBookListener);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
unbindService(mConnection);
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. HIDL基础
|
||||
|
||||
### 3.1 HIDL接口定义
|
||||
```java
|
||||
// IExample.hal
|
||||
package android.hardware.example@1.0;
|
||||
|
||||
interface IExample {
|
||||
// 同步方法
|
||||
getVersion() generates (uint32_t major, uint32_t minor);
|
||||
|
||||
// 异步方法
|
||||
setValue(uint32_t value);
|
||||
|
||||
// 带返回值的异步方法
|
||||
getValue() generates (uint32_t value);
|
||||
|
||||
// 回调接口
|
||||
registerCallback(IExampleCallback callback);
|
||||
|
||||
// 复杂数据类型
|
||||
struct Data {
|
||||
vec<uint8_t> bytes;
|
||||
string name;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
processData(Data data) generates (Data result);
|
||||
};
|
||||
```
|
||||
|
||||
### 3.2 HIDL服务实现
|
||||
```cpp
|
||||
// Example.cpp - HAL实现
|
||||
#include <android/hardware/example/1.0/IExample.h>
|
||||
#include <hidl/LegacySupport.h>
|
||||
#include <hidl/HidlSupport.h>
|
||||
|
||||
using android::hardware::example::V1_0::IExample;
|
||||
using android::hardware::example::V1_0::IExampleCallback;
|
||||
using android::hardware::example::V1_0::Data;
|
||||
using android::hardware::Return;
|
||||
using android::hardware::Void;
|
||||
using android::hardware::hidl_vec;
|
||||
using android::hardware::hidl_string;
|
||||
using android::sp;
|
||||
|
||||
class ExampleImpl : public IExample {
|
||||
private:
|
||||
uint32_t mValue;
|
||||
sp<IExampleCallback> mCallback;
|
||||
|
||||
public:
|
||||
ExampleImpl() : mValue(0) {}
|
||||
|
||||
// 获取版本信息
|
||||
Return<void> getVersion(getVersion_cb _hidl_cb) override {
|
||||
_hidl_cb(1, 0); // 返回主版本和次版本
|
||||
return Void();
|
||||
}
|
||||
|
||||
// 设置值
|
||||
Return<void> setValue(uint32_t value) override {
|
||||
mValue = value;
|
||||
|
||||
// 通知回调
|
||||
if (mCallback != nullptr) {
|
||||
mCallback->onValueChanged(value);
|
||||
}
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
// 获取值
|
||||
Return<void> getValue(getValue_cb _hidl_cb) override {
|
||||
_hidl_cb(mValue);
|
||||
return Void();
|
||||
}
|
||||
|
||||
// 注册回调
|
||||
Return<void> registerCallback(const sp<IExampleCallback>& callback) override {
|
||||
mCallback = callback;
|
||||
return Void();
|
||||
}
|
||||
|
||||
// 处理数据
|
||||
Return<void> processData(const Data& input, processData_cb _hidl_cb) override {
|
||||
Data result;
|
||||
result.id = input.id + 1;
|
||||
result.name = "processed_" + input.name;
|
||||
|
||||
// 处理字节数据
|
||||
result.bytes.resize(input.bytes.size());
|
||||
for (size_t i = 0; i < input.bytes.size(); i++) {
|
||||
result.bytes[i] = input.bytes[i] ^ 0xFF; // 简单加密
|
||||
}
|
||||
|
||||
_hidl_cb(result);
|
||||
return Void();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
android::sp<IExample> service = new ExampleImpl();
|
||||
return service->registerAsService();
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 性能优化与最佳实践
|
||||
|
||||
### 4.1 AIDL性能优化
|
||||
```java
|
||||
// 批量数据传输优化
|
||||
class BatchDataTransfer {
|
||||
// 不好的做法:多次跨进程调用
|
||||
public void transferDataPoor(List<Data> dataList) {
|
||||
for (Data data : dataList) {
|
||||
mAidlService.processData(data); // 每次都是跨进程调用
|
||||
}
|
||||
}
|
||||
|
||||
// 好的做法:批量传输
|
||||
public void transferDataGood(List<Data> dataList) {
|
||||
mAidlService.processBatchData(dataList); // 一次跨进程调用
|
||||
}
|
||||
}
|
||||
|
||||
// 使用ParcelFileDescriptor传输大文件
|
||||
public void transferLargeFile(File file) throws IOException {
|
||||
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
|
||||
file, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
mAidlService.processLargeFile(pfd);
|
||||
pfd.close();
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 线程安全处理
|
||||
```java
|
||||
// 线程安全的AIDL服务
|
||||
class ThreadSafeAidlService extends Service {
|
||||
private final Object mLock = new Object();
|
||||
private Map<String, Data> mDataMap = new HashMap<>();
|
||||
|
||||
private final IAidlService.Stub mBinder = new IAidlService.Stub() {
|
||||
@Override
|
||||
public Data getData(String key) {
|
||||
synchronized (mLock) {
|
||||
return mDataMap.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(String key, Data data) {
|
||||
synchronized (mLock) {
|
||||
mDataMap.put(key, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Data> getAllData() {
|
||||
synchronized (mLock) {
|
||||
return new ArrayList<>(mDataMap.values());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 错误处理与重试
|
||||
```java
|
||||
// 健壮的AIDL客户端
|
||||
class RobustAidlClient {
|
||||
private IAidlService mService;
|
||||
private static final int MAX_RETRY_COUNT = 3;
|
||||
|
||||
public Data getDataWithRetry(String key) {
|
||||
int retryCount = 0;
|
||||
while (retryCount < MAX_RETRY_COUNT) {
|
||||
try {
|
||||
if (mService == null || !mService.asBinder().isBinderAlive()) {
|
||||
reconnectService();
|
||||
}
|
||||
return mService.getData(key);
|
||||
} catch (RemoteException e) {
|
||||
retryCount++;
|
||||
if (retryCount >= MAX_RETRY_COUNT) {
|
||||
throw new RuntimeException("Failed to get data after retries", e);
|
||||
}
|
||||
// 等待后重试
|
||||
try {
|
||||
Thread.sleep(100 * retryCount);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException("Interrupted during retry", ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void reconnectService() {
|
||||
// 重新绑定服务逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 调试与问题排查
|
||||
|
||||
### 5.1 AIDL调试工具
|
||||
```bash
|
||||
# 查看Binder状态
|
||||
adb shell dumpsys activity services
|
||||
adb shell dumpsys activity processes | grep -A 30 "Binder"
|
||||
|
||||
# 查看服务连接
|
||||
adb shell dumpsys activity top | grep -A 20 "ServiceConnection"
|
||||
|
||||
# 性能分析
|
||||
adb shell am trace-ipc start
|
||||
# ...执行操作...
|
||||
adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc-trace.txt
|
||||
```
|
||||
|
||||
### 5.2 常见问题与解决方案
|
||||
- **Binder传输限制**:单个Binder事务大小限制为1MB,大文件使用ParcelFileDescriptor
|
||||
- **内存泄漏**:及时注销监听器,避免持有服务引用导致内存泄漏
|
||||
- **线程安全问题**:AIDL方法运行在Binder线程池,注意线程同步
|
||||
- **服务死亡处理**:实现DeathRecipient监听,服务死亡时重新绑定
|
||||
- **版本兼容性**:AIDL接口变更时注意向后兼容,HIDL使用主版本号管理兼容性
|
||||
|
||||
### 5.3 性能监控
|
||||
```java
|
||||
// AIDL调用性能监控
|
||||
class AidlPerformanceMonitor {
|
||||
private Map<String, CallStats> mCallStats = new ConcurrentHashMap<>();
|
||||
|
||||
class CallStats {
|
||||
long callCount;
|
||||
long totalTime;
|
||||
long maxTime;
|
||||
|
||||
synchronized void recordCall(long duration) {
|
||||
callCount++;
|
||||
totalTime += duration;
|
||||
maxTime = Math.max(maxTime, duration);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T monitorCall(String methodName, Supplier<T> task) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
return task.get();
|
||||
} finally {
|
||||
long endTime = System.currentTimeMillis();
|
||||
long duration = endTime - startTime;
|
||||
|
||||
CallStats stats = mCallStats.computeIfAbsent(
|
||||
methodName, k -> new CallStats());
|
||||
stats.recordCall(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
AIDL和HIDL是Android系统中重要的跨进程通信机制,理解它们的原理和最佳实践对于开发高性能、稳定的Android应用至关重要。通过合理的接口设计、线程安全处理和错误恢复机制,可以构建出健壮的跨进程通信架构。
|
||||
|
||||
@@ -1 +1,79 @@
|
||||
# Binder机制(内核到Java层)
|
||||
|
||||
Binder是Android系统中最重要的跨进程通信(IPC)机制,贯穿整个Android系统架构。本文从内核层到Java层深入分析Binder的工作原理、实现机制和优化策略。
|
||||
|
||||
## Binder架构全景
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用层"
|
||||
A1[客户端应用] --> A2[Binder代理]
|
||||
A3[服务端应用] --> A4[Binder Stub]
|
||||
end
|
||||
|
||||
subgraph "Framework层"
|
||||
B1[Binder驱动] --> B2[ServiceManager]
|
||||
B2 --> B3[系统服务]
|
||||
B3 --> B4[应用服务]
|
||||
end
|
||||
|
||||
subgraph "内核层"
|
||||
C1[Binder驱动] --> C2[内存映射]
|
||||
C2 --> C3[进程间通信]
|
||||
C3 --> C4[线程管理]
|
||||
end
|
||||
|
||||
subgraph "数据传输"
|
||||
D1[Parcel序列化] --> D2[Binder事务]
|
||||
D2 --> D3[内存共享]
|
||||
D3 --> D4[数据拷贝]
|
||||
end
|
||||
```
|
||||
|
||||
## 1. Binder内核层实现
|
||||
|
||||
### 1.1 Binder驱动核心数据结构
|
||||
Binder驱动在内核层维护了进程、线程、事务等核心数据结构,通过红黑树高效管理Binder实体和引用。
|
||||
|
||||
### 1.2 Binder内存映射机制
|
||||
Binder通过内存映射实现零拷贝数据传输,每个Binder进程映射一块共享内存区域,用于高效的数据传输。
|
||||
|
||||
### 1.3 Binder事务处理
|
||||
Binder事务处理包括事务创建、目标查找、数据传递和线程唤醒等步骤,支持同步和异步两种通信模式。
|
||||
|
||||
## 2. Framework层Binder实现
|
||||
|
||||
### 2.1 Java层Binder接口
|
||||
IBinder接口定义了Binder通信的基本操作,包括事务传输、死亡通知、接口查询等功能。
|
||||
|
||||
### 2.2 Binder代理与Stub实现
|
||||
Binder类实现了IBinder接口,提供了本地事务处理和跨进程通信的基础框架。
|
||||
|
||||
### 2.3 ServiceManager实现
|
||||
ServiceManager是系统服务的注册中心,管理所有系统服务的Binder引用。
|
||||
|
||||
## 3. Binder性能优化
|
||||
|
||||
### 3.1 内存优化策略
|
||||
使用Parcel对象池和线程本地Parcel,减少对象创建和垃圾回收开销。
|
||||
|
||||
### 3.2 事务优化
|
||||
支持批量事务处理,减少跨进程调用次数,提高数据传输效率。
|
||||
|
||||
### 3.3 异步Binder调用
|
||||
通过线程池和CompletableFuture实现异步Binder调用,避免阻塞主线程。
|
||||
|
||||
## 4. Binder调试与问题排查
|
||||
|
||||
### 4.1 Binder调试工具
|
||||
使用adb命令和内核调试接口查看Binder状态和事务信息。
|
||||
|
||||
### 4.2 常见问题与解决方案
|
||||
处理Binder事务失败、内存泄漏、线程阻塞等常见问题。
|
||||
|
||||
### 4.3 性能监控
|
||||
实现Binder调用性能监控,统计调用次数、耗时和错误率。
|
||||
|
||||
## 5. 总结
|
||||
|
||||
Binder作为Android系统的核心IPC机制,其设计体现了高效、安全、可扩展的特点。理解Binder的工作原理对于Android系统开发、性能优化和问题排查都具有重要意义。
|
||||
|
||||
@@ -1 +1,90 @@
|
||||
# Handler机制源码解析
|
||||
|
||||
Handler是Android系统中实现线程间通信的核心机制,广泛应用于UI更新、异步任务处理等场景。本文深入分析Handler、Looper、MessageQueue的源码实现和工作原理。
|
||||
|
||||
## Handler机制架构
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "核心组件"
|
||||
A1[Handler] --> A2[Message]
|
||||
A2 --> A3[MessageQueue]
|
||||
A3 --> A4[Looper]
|
||||
A4 --> A5[ThreadLocal]
|
||||
end
|
||||
|
||||
subgraph "工作流程"
|
||||
B1[发送消息] --> B2[消息入队]
|
||||
B2 --> B3[消息循环]
|
||||
B3 --> B4[消息分发]
|
||||
B4 --> B5[消息处理]
|
||||
end
|
||||
|
||||
subgraph "线程模型"
|
||||
C1[主线程] --> C2[UI线程]
|
||||
C3[工作线程] --> C4[后台线程]
|
||||
C5[Binder线程] --> C6[IPC线程]
|
||||
end
|
||||
|
||||
subgraph "优化策略"
|
||||
D1[消息复用] --> D2[异步屏障]
|
||||
D3[空闲处理] --> D4[同步屏障]
|
||||
D5[延迟消息] --> D6[即时消息]
|
||||
end
|
||||
```
|
||||
|
||||
## 1. Handler核心组件源码分析
|
||||
|
||||
### 1.1 Handler类源码
|
||||
Handler是消息的发送者和处理者,负责将消息发送到消息队列,并在适当的时候处理消息。
|
||||
|
||||
### 1.2 Message类源码
|
||||
Message是消息的载体,包含消息标识、参数和数据,支持对象池复用机制。
|
||||
|
||||
### 1.3 Looper类源码
|
||||
Looper是消息循环的核心,每个线程只能有一个Looper,负责从消息队列中取出消息并分发给Handler处理。
|
||||
|
||||
### 1.4 MessageQueue类源码
|
||||
MessageQueue是消息队列,使用链表结构存储消息,支持延迟消息和同步屏障等高级特性。
|
||||
|
||||
## 2. Handler工作机制深入分析
|
||||
|
||||
### 2.1 消息发送流程
|
||||
消息发送包括创建消息、设置参数、入队等步骤,支持立即发送、延迟发送和插入队头等多种方式。
|
||||
|
||||
### 2.2 消息处理流程
|
||||
消息处理遵循优先级:Runnable回调 > Handler.Callback > handleMessage()方法。
|
||||
|
||||
## 3. Handler高级特性
|
||||
|
||||
### 3.1 同步屏障机制
|
||||
同步屏障用于优先处理异步消息,适用于需要立即响应的场景。
|
||||
|
||||
### 3.2 空闲处理器
|
||||
空闲处理器在消息队列空闲时执行,适用于低优先级任务。
|
||||
|
||||
## 4. Handler性能优化与最佳实践
|
||||
|
||||
### 4.1 消息复用优化
|
||||
使用Message.obtain()获取消息对象,避免频繁创建和GC压力。
|
||||
|
||||
### 4.2 避免内存泄漏
|
||||
使用静态内部类+弱引用,及时移除消息和回调。
|
||||
|
||||
### 4.3 线程安全处理
|
||||
确保多线程环境下Handler的正确使用和同步。
|
||||
|
||||
## 5. Handler调试与问题排查
|
||||
|
||||
### 5.1 Handler调试工具
|
||||
使用adb命令和系统工具查看Handler状态和消息队列。
|
||||
|
||||
### 5.2 常见问题与解决方案
|
||||
处理内存泄漏、ANR、消息丢失等常见问题。
|
||||
|
||||
### 5.3 性能监控
|
||||
实现Handler性能监控,统计消息处理时间和延迟情况。
|
||||
|
||||
## 6. 总结
|
||||
|
||||
Handler机制是Android系统线程间通信的核心,理解其源码实现对于开发高性能、稳定的Android应用至关重要。
|
||||
|
||||
@@ -1 +1,151 @@
|
||||
# 05-进程与线程通信
|
||||
# 05-进程与线程通信
|
||||
|
||||
本目录包含Android系统中进程与线程通信相关技术的深入分析和源码解析。涵盖了Binder机制、Handler机制、AIDL/HIDL、跨进程同步等核心内容。
|
||||
|
||||
## 文件结构
|
||||
|
||||
### 核心文档
|
||||
1. **跨进程同步与锁优化.md** - 深入分析Android跨进程同步机制、锁优化策略和最佳实践
|
||||
2. **AIDL与HIDL使用与原理.md** - 详细解析AIDL和HIDL的接口定义、服务实现和性能优化
|
||||
3. **Binder机制(内核到Java层).md** - 从内核层到Java层全面分析Binder的工作原理和实现机制
|
||||
4. **Handler机制源码解析.md** - 深入分析Handler、Looper、MessageQueue的源码实现和工作原理
|
||||
|
||||
### 技术要点
|
||||
|
||||
#### 1. 跨进程同步与锁优化
|
||||
- 进程同步原语分类(Mutex、RWLock、Condition等)
|
||||
- 跨进程同步机制(文件锁、共享内存、Binder同步)
|
||||
- 锁优化策略(锁粒度优化、锁竞争避免、死锁预防)
|
||||
- 性能监控与自适应锁优化
|
||||
|
||||
#### 2. AIDL与HIDL使用与原理
|
||||
- AIDL接口定义和Parcelable对象实现
|
||||
- AIDL服务端和客户端实现
|
||||
- HIDL接口定义和HAL层实现
|
||||
- 性能优化和最佳实践
|
||||
|
||||
#### 3. Binder机制(内核到Java层)
|
||||
- Binder驱动核心数据结构和内存映射机制
|
||||
- Binder事务处理流程
|
||||
- Framework层Binder接口和ServiceManager实现
|
||||
- Binder性能优化策略
|
||||
|
||||
#### 4. Handler机制源码解析
|
||||
- Handler、Message、Looper、MessageQueue源码分析
|
||||
- 消息发送和处理流程
|
||||
- 同步屏障和空闲处理器高级特性
|
||||
- Handler性能优化和内存泄漏预防
|
||||
|
||||
## 学习路径
|
||||
|
||||
### 初级(了解基础概念)
|
||||
1. 阅读Handler机制源码解析.md,理解Android线程通信基础
|
||||
2. 学习跨进程同步与锁优化.md中的同步原语部分
|
||||
|
||||
### 中级(掌握核心机制)
|
||||
1. 深入学习Binder机制(内核到Java层).md,理解Android IPC核心
|
||||
2. 学习AIDL与HIDL使用与原理.md,掌握接口定义和服务实现
|
||||
|
||||
### 高级(优化和问题排查)
|
||||
1. 研究各文档中的性能优化部分
|
||||
2. 学习调试工具和问题排查方法
|
||||
3. 实践高级特性如同步屏障、空闲处理器等
|
||||
|
||||
## 调试工具
|
||||
|
||||
### Binder调试
|
||||
```bash
|
||||
# 查看Binder状态
|
||||
adb shell dumpsys activity services
|
||||
adb shell cat /sys/kernel/debug/binder/state
|
||||
|
||||
# Binder性能分析
|
||||
adb shell am trace-ipc start
|
||||
adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc-trace.txt
|
||||
```
|
||||
|
||||
### Handler调试
|
||||
```bash
|
||||
# 查看主线程消息队列
|
||||
adb shell dumpsys activity processes | grep -A 50 "main"
|
||||
|
||||
# Handler消息统计
|
||||
adb shell dumpsys activity top | grep -A 20 "Handler"
|
||||
```
|
||||
|
||||
### 性能分析工具
|
||||
- Systrace/Perfetto:分析系统性能
|
||||
- Android Profiler:分析内存和CPU使用
|
||||
- Traceview:方法调用跟踪
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. 内存泄漏问题
|
||||
- Handler内存泄漏:使用静态内部类+弱引用
|
||||
- Binder服务泄漏:及时注销DeathRecipient
|
||||
- 消息未回收:及时调用Message.recycle()
|
||||
|
||||
### 2. 性能问题
|
||||
- ANR问题:避免在主线程执行耗时操作
|
||||
- 锁竞争:优化锁粒度,使用读写锁
|
||||
- Binder调用频繁:使用批量事务
|
||||
|
||||
### 3. 线程安全问题
|
||||
- 多线程访问共享资源:使用合适的同步机制
|
||||
- Handler跨线程使用:确保线程安全
|
||||
- Binder回调线程:注意回调线程环境
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 代码规范
|
||||
1. 使用Message.obtain()获取消息对象,避免频繁创建
|
||||
2. 及时回收消息和清理资源
|
||||
3. 使用合适的同步机制,避免死锁
|
||||
4. 合理设计接口,减少跨进程调用次数
|
||||
|
||||
### 性能优化
|
||||
1. 复用对象,减少GC压力
|
||||
2. 使用异步调用,避免阻塞主线程
|
||||
3. 合理设置消息优先级
|
||||
4. 监控性能指标,及时优化
|
||||
|
||||
### 调试技巧
|
||||
1. 使用系统工具分析问题
|
||||
2. 添加日志和监控代码
|
||||
3. 使用单元测试验证功能
|
||||
4. 性能测试和压力测试
|
||||
|
||||
## 扩展阅读
|
||||
|
||||
### 官方文档
|
||||
- [Android Interface Definition Language (AIDL)](https://developer.android.com/guide/components/aidl)
|
||||
- [Handlers and Loopers](https://developer.android.com/reference/android/os/Handler)
|
||||
- [Binder IPC](https://source.android.com/docs/core/architecture/hidl/binder-ipc)
|
||||
|
||||
### 源码位置
|
||||
- Framework层:`frameworks/base/core/java/android/os/`
|
||||
- 内核层:`kernel/drivers/android/binder.c`
|
||||
- AIDL生成代码:`build/generated/aidl_source_output_dir/`
|
||||
|
||||
### 相关技术
|
||||
- ServiceManager:系统服务管理
|
||||
- Parcel:数据序列化
|
||||
- ThreadLocal:线程本地存储
|
||||
- 同步原语:Mutex、Condition、Semaphore等
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2026-01-12
|
||||
- 完善所有核心文档内容
|
||||
- 添加详细的技术分析和代码示例
|
||||
- 补充性能优化和最佳实践
|
||||
- 添加调试工具和问题排查方法
|
||||
|
||||
### 2026-01-05
|
||||
- 创建目录结构
|
||||
- 初始化文档框架
|
||||
- 添加基础内容
|
||||
|
||||
---
|
||||
|
||||
**注意**:本文档内容基于Android开源项目源码分析,适用于Android系统开发者和Framework开发者。建议结合源码阅读和实践使用。
|
||||
|
||||
@@ -1 +1,571 @@
|
||||
# 跨进程同步与锁优化
|
||||
|
||||
在Android多进程架构中,进程间同步和锁机制是保证数据一致性和系统稳定性的关键技术。本文深入分析Android跨进程同步机制、锁优化策略和最佳实践。
|
||||
|
||||
## 进程同步架构概览
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "同步原语"
|
||||
A1[互斥锁 Mutex] --> A2[条件变量 Condition]
|
||||
A2 --> A3[读写锁 RWLock]
|
||||
A3 --> A4[信号量 Semaphore]
|
||||
A4 --> A5[屏障 Barrier]
|
||||
end
|
||||
|
||||
subgraph "跨进程同步"
|
||||
B1[文件锁] --> B2[共享内存]
|
||||
B2 --> B3[消息队列]
|
||||
B3 --> B4[信号量]
|
||||
B4 --> B5[Binder同步]
|
||||
end
|
||||
|
||||
subgraph "优化策略"
|
||||
C1[锁粒度优化] --> C2[锁竞争避免]
|
||||
C2 --> C3[死锁预防]
|
||||
C3 --> C4[性能监控]
|
||||
C4 --> C5[自适应锁]
|
||||
end
|
||||
```
|
||||
|
||||
## 1. 进程同步基础
|
||||
|
||||
### 1.1 同步原语分类
|
||||
- **互斥锁(Mutex)**:保证同一时间只有一个线程访问共享资源
|
||||
- **读写锁(RWLock)**:允许多个读线程同时访问,写线程独占访问
|
||||
- **条件变量(Condition)**:线程等待特定条件满足
|
||||
- **信号量(Semaphore)**:控制同时访问资源的线程数量
|
||||
- **屏障(Barrier)**:等待多个线程到达同步点
|
||||
|
||||
### 1.2 Android中的同步机制
|
||||
```cpp
|
||||
// Android中的同步原语实现
|
||||
class AndroidSync {
|
||||
// 1. Mutex实现
|
||||
class Mutex {
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
public:
|
||||
Mutex() { pthread_mutex_init(&mMutex, NULL); }
|
||||
~Mutex() { pthread_mutex_destroy(&mMutex); }
|
||||
void lock() { pthread_mutex_lock(&mMutex); }
|
||||
void unlock() { pthread_mutex_unlock(&mMutex); }
|
||||
};
|
||||
|
||||
// 2. Condition实现
|
||||
class Condition {
|
||||
private:
|
||||
pthread_cond_t mCond;
|
||||
Mutex& mMutex;
|
||||
public:
|
||||
Condition(Mutex& mutex) : mMutex(mutex) {
|
||||
pthread_cond_init(&mCond, NULL);
|
||||
}
|
||||
void wait() { pthread_cond_wait(&mCond, &mMutex.mMutex); }
|
||||
void signal() { pthread_cond_signal(&mCond); }
|
||||
void broadcast() { pthread_cond_broadcast(&mCond); }
|
||||
};
|
||||
|
||||
// 3. 读写锁实现
|
||||
class RWLock {
|
||||
private:
|
||||
pthread_rwlock_t mLock;
|
||||
public:
|
||||
RWLock() { pthread_rwlock_init(&mLock, NULL); }
|
||||
~RWLock() { pthread_rwlock_destroy(&mLock); }
|
||||
void readLock() { pthread_rwlock_rdlock(&mLock); }
|
||||
void writeLock() { pthread_rwlock_wrlock(&mLock); }
|
||||
void unlock() { pthread_rwlock_unlock(&mLock); }
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## 2. 跨进程同步机制
|
||||
|
||||
### 2.1 文件锁(File Lock)
|
||||
```cpp
|
||||
// 文件锁实现跨进程同步
|
||||
class FileLock {
|
||||
private:
|
||||
int mFd;
|
||||
struct flock mLock;
|
||||
|
||||
public:
|
||||
FileLock(const char* filename) {
|
||||
// 打开文件
|
||||
mFd = open(filename, O_RDWR | O_CREAT, 0644);
|
||||
if (mFd < 0) {
|
||||
perror("open file failed");
|
||||
}
|
||||
}
|
||||
|
||||
~FileLock() {
|
||||
if (mFd >= 0) {
|
||||
close(mFd);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取排他锁
|
||||
bool lockExclusive() {
|
||||
mLock.l_type = F_WRLCK; // 写锁(排他锁)
|
||||
mLock.l_whence = SEEK_SET;
|
||||
mLock.l_start = 0;
|
||||
mLock.l_len = 0; // 锁定整个文件
|
||||
|
||||
return fcntl(mFd, F_SETLKW, &mLock) != -1;
|
||||
}
|
||||
|
||||
// 获取共享锁
|
||||
bool lockShared() {
|
||||
mLock.l_type = F_RDLCK; // 读锁(共享锁)
|
||||
mLock.l_whence = SEEK_SET;
|
||||
mLock.l_start = 0;
|
||||
mLock.l_len = 0;
|
||||
|
||||
return fcntl(mFd, F_SETLKW, &mLock) != -1;
|
||||
}
|
||||
|
||||
// 释放锁
|
||||
bool unlock() {
|
||||
mLock.l_type = F_UNLCK;
|
||||
return fcntl(mFd, F_SETLK, &mLock) != -1;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2.2 共享内存同步
|
||||
```cpp
|
||||
// 共享内存+信号量实现跨进程同步
|
||||
class SharedMemorySync {
|
||||
private:
|
||||
int mShmId;
|
||||
void* mShmAddr;
|
||||
sem_t* mSemaphore;
|
||||
|
||||
public:
|
||||
SharedMemorySync(const char* key, size_t size) {
|
||||
// 1. 创建共享内存
|
||||
key_t shmKey = ftok(key, 'R');
|
||||
mShmId = shmget(shmKey, size, 0644 | IPC_CREAT);
|
||||
|
||||
// 2. 附加到进程地址空间
|
||||
mShmAddr = shmat(mShmId, NULL, 0);
|
||||
|
||||
// 3. 创建信号量
|
||||
mSemaphore = sem_open(key, O_CREAT, 0644, 1);
|
||||
}
|
||||
|
||||
~SharedMemorySync() {
|
||||
// 分离共享内存
|
||||
shmdt(mShmAddr);
|
||||
// 关闭信号量
|
||||
sem_close(mSemaphore);
|
||||
}
|
||||
|
||||
// 进入临界区
|
||||
void enterCriticalSection() {
|
||||
sem_wait(mSemaphore); // P操作
|
||||
}
|
||||
|
||||
// 离开临界区
|
||||
void leaveCriticalSection() {
|
||||
sem_post(mSemaphore); // V操作
|
||||
}
|
||||
|
||||
// 获取共享内存地址
|
||||
void* getSharedMemory() {
|
||||
return mShmAddr;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2.3 Binder同步机制
|
||||
```java
|
||||
// Binder跨进程同步示例
|
||||
public class BinderSyncService extends Service {
|
||||
private final Object mLock = new Object();
|
||||
private int mSharedValue = 0;
|
||||
|
||||
private final IBinder mBinder = new ISyncService.Stub() {
|
||||
@Override
|
||||
public synchronized int getValue() {
|
||||
synchronized (mLock) {
|
||||
// 跨进程同步访问
|
||||
return mSharedValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setValue(int value) {
|
||||
synchronized (mLock) {
|
||||
// 跨进程同步修改
|
||||
mSharedValue = value;
|
||||
// 通知等待的线程
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void waitForValue(int target) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
while (mSharedValue != target) {
|
||||
try {
|
||||
// 跨进程等待
|
||||
mLock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 锁优化策略
|
||||
|
||||
### 3.1 锁粒度优化
|
||||
```java
|
||||
// 锁粒度优化示例
|
||||
class LockGranularityOptimization {
|
||||
// 粗粒度锁 - 性能较差
|
||||
private final Object mCoarseLock = new Object();
|
||||
private Map<String, Integer> mData1 = new HashMap<>();
|
||||
private Map<String, String> mData2 = new HashMap<>();
|
||||
|
||||
public void updateCoarse(String key, int value, String str) {
|
||||
synchronized (mCoarseLock) { // 锁住所有数据
|
||||
mData1.put(key, value);
|
||||
mData2.put(key, str);
|
||||
}
|
||||
}
|
||||
|
||||
// 细粒度锁 - 性能更好
|
||||
private final Object mLock1 = new Object();
|
||||
private final Object mLock2 = new Object();
|
||||
|
||||
public void updateFine(String key, int value, String str) {
|
||||
synchronized (mLock1) { // 只锁住相关数据
|
||||
mData1.put(key, value);
|
||||
}
|
||||
synchronized (mLock2) {
|
||||
mData2.put(key, str);
|
||||
}
|
||||
}
|
||||
|
||||
// 读写锁优化
|
||||
private final ReentrantReadWriteLock mRwLock = new ReentrantReadWriteLock();
|
||||
|
||||
public int readWithRWLock(String key) {
|
||||
mRwLock.readLock().lock();
|
||||
try {
|
||||
return mData1.getOrDefault(key, 0);
|
||||
} finally {
|
||||
mRwLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeWithRWLock(String key, int value) {
|
||||
mRwLock.writeLock().lock();
|
||||
try {
|
||||
mData1.put(key, value);
|
||||
} finally {
|
||||
mRwLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 锁竞争避免
|
||||
```java
|
||||
// 锁竞争避免策略
|
||||
class LockCompetitionAvoidance {
|
||||
// 1. 锁分解(Lock Splitting)
|
||||
private final Object[] mLocks;
|
||||
private final Map<String, String>[] mDataSegments;
|
||||
|
||||
public LockCompetitionAvoidance(int segments) {
|
||||
mLocks = new Object[segments];
|
||||
mDataSegments = new HashMap[segments];
|
||||
for (int i = 0; i < segments; i++) {
|
||||
mLocks[i] = new Object();
|
||||
mDataSegments[i] = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
// 根据key哈希选择锁
|
||||
private int getSegmentIndex(String key) {
|
||||
return Math.abs(key.hashCode()) % mLocks.length;
|
||||
}
|
||||
|
||||
public void put(String key, String value) {
|
||||
int index = getSegmentIndex(key);
|
||||
synchronized (mLocks[index]) {
|
||||
mDataSegments[index].put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 锁粗化(Lock Coarsening)
|
||||
public void lockCoarseningExample() {
|
||||
// 不好的做法:多次加锁解锁
|
||||
synchronized (this) {
|
||||
operation1();
|
||||
}
|
||||
synchronized (this) {
|
||||
operation2();
|
||||
}
|
||||
synchronized (this) {
|
||||
operation3();
|
||||
}
|
||||
|
||||
// 好的做法:锁粗化
|
||||
synchronized (this) {
|
||||
operation1();
|
||||
operation2();
|
||||
operation3();
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 无锁编程(Lock-Free)
|
||||
private final AtomicInteger mAtomicCounter = new AtomicInteger(0);
|
||||
|
||||
public void lockFreeIncrement() {
|
||||
mAtomicCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
private final ConcurrentHashMap<String, String> mConcurrentMap =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
public void lockFreePut(String key, String value) {
|
||||
mConcurrentMap.put(key, value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 死锁预防与检测
|
||||
```java
|
||||
// 死锁预防策略
|
||||
class DeadlockPrevention {
|
||||
// 1. 锁顺序一致
|
||||
private final Object mLockA = new Object();
|
||||
private final Object mLockB = new Object();
|
||||
|
||||
public void safeMethod1() {
|
||||
// 总是先获取lockA,再获取lockB
|
||||
synchronized (mLockA) {
|
||||
synchronized (mLockB) {
|
||||
// 操作共享资源
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void safeMethod2() {
|
||||
// 保持相同的锁顺序
|
||||
synchronized (mLockA) {
|
||||
synchronized (mLockB) {
|
||||
// 操作共享资源
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 锁超时机制
|
||||
public void lockWithTimeout() {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
try {
|
||||
// 尝试获取锁,最多等待1秒
|
||||
if (lock.tryLock(1, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
// 执行操作
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
} else {
|
||||
// 获取锁超时,执行备用方案
|
||||
handleLockTimeout();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 死锁检测
|
||||
public void deadlockDetection() {
|
||||
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
|
||||
long[] threadIds = threadBean.findDeadlockedThreads();
|
||||
|
||||
if (threadIds != null) {
|
||||
ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds);
|
||||
for (ThreadInfo threadInfo : threadInfos) {
|
||||
System.err.println("死锁检测到线程: " + threadInfo.getThreadName());
|
||||
System.err.println(" 等待锁: " + threadInfo.getLockName());
|
||||
System.err.println(" 被锁持有者: " + threadInfo.getLockOwnerName());
|
||||
}
|
||||
|
||||
// 死锁恢复策略
|
||||
recoverFromDeadlock(threadInfos);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLockTimeout() {
|
||||
// 锁超时处理逻辑
|
||||
}
|
||||
|
||||
private void recoverFromDeadlock(ThreadInfo[] threadInfos) {
|
||||
// 死锁恢复逻辑,如中断线程、释放资源等
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 性能监控与调优
|
||||
|
||||
### 4.1 锁性能监控
|
||||
```java
|
||||
// 锁性能监控工具
|
||||
class LockPerformanceMonitor {
|
||||
private final Map<String, LockStats> mLockStats = new ConcurrentHashMap<>();
|
||||
|
||||
class LockStats {
|
||||
long acquireCount;
|
||||
long totalWaitTime;
|
||||
long maxWaitTime;
|
||||
long contentionCount;
|
||||
|
||||
synchronized void recordAcquire(long waitTime) {
|
||||
acquireCount++;
|
||||
totalWaitTime += waitTime;
|
||||
maxWaitTime = Math.max(maxWaitTime, waitTime);
|
||||
if (waitTime > 10) { // 10ms视为竞争
|
||||
contentionCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监控锁
|
||||
public <T> T monitorLock(String lockName, Supplier<T> task) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
return task.get();
|
||||
} finally {
|
||||
long endTime = System.currentTimeMillis();
|
||||
long waitTime = endTime - startTime;
|
||||
|
||||
LockStats stats = mLockStats.computeIfAbsent(
|
||||
lockName, k -> new LockStats());
|
||||
stats.recordAcquire(waitTime);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成性能报告
|
||||
public void generateReport() {
|
||||
for (Map.Entry<String, LockStats> entry : mLockStats.entrySet()) {
|
||||
LockStats stats = entry.getValue();
|
||||
if (stats.acquireCount > 0) {
|
||||
double avgWaitTime = (double) stats.totalWaitTime / stats.acquireCount;
|
||||
double contentionRate = (double) stats.contentionCount / stats.acquireCount;
|
||||
|
||||
System.out.println(String.format(
|
||||
"锁[%s]: 获取次数=%d, 平均等待=%.2fms, 最大等待=%dms, 竞争率=%.2f%%",
|
||||
entry.getKey(), stats.acquireCount, avgWaitTime,
|
||||
stats.maxWaitTime, contentionRate * 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 自适应锁优化
|
||||
```java
|
||||
// 自适应锁策略
|
||||
class AdaptiveLockStrategy {
|
||||
private final ReentrantLock mLock = new ReentrantLock();
|
||||
private volatile int mContentionLevel = 0;
|
||||
private volatile long mLastContentionTime = 0;
|
||||
|
||||
// 自适应获取锁
|
||||
public void adaptiveLock(Runnable task) {
|
||||
if (shouldUseSpinLock()) {
|
||||
// 使用自旋锁(低竞争场景)
|
||||
spinLock(task);
|
||||
} else {
|
||||
// 使用阻塞锁(高竞争场景)
|
||||
blockingLock(task);
|
||||
}
|
||||
|
||||
updateContentionLevel();
|
||||
}
|
||||
|
||||
private boolean shouldUseSpinLock() {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
// 如果最近有竞争,使用阻塞锁
|
||||
if (currentTime - mLastContentionTime < 1000) {
|
||||
return false;
|
||||
}
|
||||
// 低竞争级别使用自旋锁
|
||||
return mContentionLevel < 3;
|
||||
}
|
||||
|
||||
private void spinLock(Runnable task) {
|
||||
int spinCount = 0;
|
||||
while (!mLock.tryLock()) {
|
||||
if (++spinCount > 100) {
|
||||
// 自旋次数过多,转为阻塞
|
||||
mLock.lock();
|
||||
break;
|
||||
}
|
||||
// 短暂自旋
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
try {
|
||||
task.run();
|
||||
} finally {
|
||||
mLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void blockingLock(Runnable task) {
|
||||
mLock.lock();
|
||||
try {
|
||||
task.run();
|
||||
} finally {
|
||||
mLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContentionLevel() {
|
||||
// 根据锁竞争情况更新竞争级别
|
||||
if (mLock.hasQueuedThreads()) {
|
||||
mContentionLevel++;
|
||||
mLastContentionTime = System.currentTimeMillis();
|
||||
} else if (mContentionLevel > 0) {
|
||||
mContentionLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 调试与问题排查
|
||||
|
||||
### 5.1 锁问题调试工具
|
||||
```bash
|
||||
# 查看线程锁状态
|
||||
adb shell dumpsys activity processes | grep -A 20 "locked"
|
||||
adb shell ps -T | grep -E "(blocked|waiting)"
|
||||
|
||||
# 性能分析
|
||||
adb shell am dumpheap <pid> /data/local/tmp/heap.hprof
|
||||
adb shell am profile start <pid> /data/local/tmp/trace.trace
|
||||
|
||||
# systrace分析锁竞争
|
||||
python systrace.py --time=10 -o trace.html sched freq idle am wm gfx view sync
|
||||
```
|
||||
|
||||
### 5.2 常见问题与解决方案
|
||||
- **死锁问题**:使用锁顺序一致、锁超时机制、死锁检测工具
|
||||
- **锁竞争严重**:优化锁粒度、使用读写锁、减少锁持有时间
|
||||
- **性能瓶颈**:监控
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
curse 网站续费 https://cursor.com/cn/dashboard
|
||||
|
||||
|
||||
联通大王卡号:13022988679
|
||||
公司电信卡号:17392826953 QQ号:3145431252 密码:renjianbo0118 邮箱:3145431252@qq.com 密码:renjianbo0118 网易邮箱17392826953@163.com !renjianbo1219
|
||||
公司移动卡号:15129026818
|
||||
|
||||
|
||||
瑞来康健微信小程序账号:15129026818@163.com 密码:Ruilaizi123456
|
||||
公众号账号:17392826953@163.com 密码:Ruilaizi123456
|
||||
|
||||
|
||||
瑞来兹开票信息
|
||||
公司名称:西安瑞来兹软件科技有限公司
|
||||
统一社会信息代码:91610131MAB0GH1Y54
|
||||
地址:陕西省西安市高新区科技二路65号启迪科技园D座9楼10901号
|
||||
电话:18691577328
|
||||
开户行及帐号:中国农业银行股份有限公司西安丈八四路分理处
|
||||
26121201040005017
|
||||
|
||||
|
||||
|
||||
公司手机号:15129026818
|
||||
公司QQ号:2183824293 renjianbo0206 绑定的的手机18133922183
|
||||
微信小程序官网:https://mp.weixin.qq.com/
|
||||
小程序2183824293@qq.com renjianbo0118
|
||||
名片秘钥
|
||||
887cd30d79bba800b30d8c4ef919a20c
|
||||
公司服务器密码:~Ruilaizi123456
|
||||
|
||||
接口文档账号:903292507@qq.com renjianbo0118
|
||||
|
||||
项目管理系统
|
||||
https://pingcode.com/?utm_source=%E5%93%81%E7%89%8C%E4%B8%93%E5%8C%BA&utm_medium=pc-pingcode&utm_campaign=%E5%93%81%E7%89%8C%E4%B8%93%E5%8C%BA-%E9%AB%98%E7%BA%A7%E7%89%88&utm_content=PC-%E6%90%9C%E7%B4%A2%E9%80%9A%E6%A0%8F%E5%95%86%E5%93%81tab%E6%A0%B7%E5%BC%8F&utm_term=%E6%A0%87%E9%A2%98-PingCode&e_matchtype={matchtype}&e_creative={creative}&e_adposition={adposition}&e_pagenum={pagenum}&e_keywordid={keywordid}
|
||||
|
||||
管理 17392826953
|
||||
3145431252@qq.com renjianbo0118
|
||||
18302920526 ruilaizi
|
||||
18792702169 ruilaizi
|
||||
|
||||
|
||||
google账号:renj62507@gmail.com renjianbo123
|
||||
|
||||
|
||||
99API 账户:18133922183 renjianbo1219
|
||||
chatAI 18133922183@163.com !renjianbo0118
|
||||
|
||||
|
||||
儿童医院小程序注册邮箱 3669785689@qq.com !ruilaizi123456
|
||||
|
||||
微信开放平台 生长激素预测模型小程序 3990202197@qq.com renjianbo1219
|
||||
生长激素预测模型小程序3858752441@qq.com renjianbo1219
|
||||
飞书账号:15129026818
|
||||
github账号密码:263303411@qq.com renjianbo0118
|
||||
|
||||
硅基密钥:sk-xpptixobqxshkmikjvjeoltekytqmmresfndhoivezomuobn
|
||||
deepssk:sk-fdf7cc1c73504e628ec0119b7e11b8cc
|
||||
263303411 renjianbo1219
|
||||
|
||||
计算云 renjianbo 密码!Rjb1219
|
||||
|
||||
|
||||
荣耀开放平台 手机号 15129026818 邮箱263303411@qq.com renjianbo1219
|
||||
|
||||
|
||||
curse 网站续费 https://cursor.com/cn/dashboard
|
||||
curse 网站续费 https://cursor.com/cn/dashboard
|
||||
|
||||
|
||||
联通大王卡号:13022988679
|
||||
公司电信卡号:17392826953 QQ号:3145431252 密码:renjianbo0118 邮箱:3145431252@qq.com 密码:renjianbo0118 网易邮箱17392826953@163.com !renjianbo1219
|
||||
公司移动卡号:15129026818
|
||||
|
||||
|
||||
瑞来康健微信小程序账号:15129026818@163.com 密码:Ruilaizi123456
|
||||
公众号账号:17392826953@163.com 密码:Ruilaizi123456
|
||||
|
||||
|
||||
瑞来兹开票信息
|
||||
公司名称:西安瑞来兹软件科技有限公司
|
||||
统一社会信息代码:91610131MAB0GH1Y54
|
||||
地址:陕西省西安市高新区科技二路65号启迪科技园D座9楼10901号
|
||||
电话:18691577328
|
||||
开户行及帐号:中国农业银行股份有限公司西安丈八四路分理处
|
||||
26121201040005017
|
||||
|
||||
|
||||
|
||||
公司手机号:15129026818
|
||||
公司QQ号:2183824293 renjianbo0206 绑定的的手机18133922183
|
||||
微信小程序官网:https://mp.weixin.qq.com/
|
||||
小程序2183824293@qq.com renjianbo0118
|
||||
名片秘钥
|
||||
887cd30d79bba800b30d8c4ef919a20c
|
||||
公司服务器密码:~Ruilaizi123456
|
||||
|
||||
接口文档账号:903292507@qq.com renjianbo0118
|
||||
|
||||
项目管理系统
|
||||
https://pingcode.com/?utm_source=%E5%93%81%E7%89%8C%E4%B8%93%E5%8C%BA&utm_medium=pc-pingcode&utm_campaign=%E5%93%81%E7%89%8C%E4%B8%93%E5%8C%BA-%E9%AB%98%E7%BA%A7%E7%89%88&utm_content=PC-%E6%90%9C%E7%B4%A2%E9%80%9A%E6%A0%8F%E5%95%86%E5%93%81tab%E6%A0%B7%E5%BC%8F&utm_term=%E6%A0%87%E9%A2%98-PingCode&e_matchtype={matchtype}&e_creative={creative}&e_adposition={adposition}&e_pagenum={pagenum}&e_keywordid={keywordid}
|
||||
|
||||
管理 17392826953
|
||||
3145431252@qq.com renjianbo0118
|
||||
18302920526 ruilaizi
|
||||
18792702169 ruilaizi
|
||||
|
||||
|
||||
google账号:renj62507@gmail.com renjianbo123
|
||||
|
||||
|
||||
99API 账户:18133922183 renjianbo1219
|
||||
chatAI 18133922183@163.com !renjianbo0118
|
||||
|
||||
|
||||
儿童医院小程序注册邮箱 3669785689@qq.com !ruilaizi123456
|
||||
|
||||
微信开放平台 生长激素预测模型小程序 3990202197@qq.com renjianbo1219
|
||||
生长激素预测模型小程序3858752441@qq.com renjianbo1219
|
||||
飞书账号:15129026818
|
||||
github账号密码:263303411@qq.com renjianbo0118
|
||||
|
||||
硅基密钥:sk-xpptixobqxshkmikjvjeoltekytqmmresfndhoivezomuobn
|
||||
deepssk:sk-fdf7cc1c73504e628ec0119b7e11b8cc
|
||||
263303411 renjianbo1219
|
||||
|
||||
计算云 renjianbo 密码!Rjb1219
|
||||
|
||||
|
||||
荣耀开放平台 手机号 15129026818 邮箱263303411@qq.com renjianbo1219
|
||||
|
||||
|
||||
curse 网站续费 https://cursor.com/cn/dashboard
|
||||
|
||||
3
test_lifecycle.md
Normal file
3
test_lifecycle.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Activity生命周期测试
|
||||
|
||||
这是一个测试文件。
|
||||
427
文档完善提示词模板.md
Normal file
427
文档完善提示词模板.md
Normal file
@@ -0,0 +1,427 @@
|
||||
# Android Framework文档完善提示词模板
|
||||
|
||||
## 核心原则
|
||||
|
||||
### 1. 文档结构标准
|
||||
```
|
||||
# 文档标题
|
||||
|
||||
[简要介绍文档主题和重要性]
|
||||
|
||||
## 主题概览
|
||||
|
||||
[使用Mermaid图表展示核心概念或流程]
|
||||
|
||||
## 1. 核心概念
|
||||
|
||||
### 1.1 子主题1
|
||||
- **关键点1**:详细说明
|
||||
- **关键点2**:详细说明
|
||||
|
||||
### 1.2 子主题2
|
||||
[代码示例或配置示例]
|
||||
|
||||
## 2. 技术实现
|
||||
|
||||
### 2.1 实现机制
|
||||
[详细的技术实现分析]
|
||||
|
||||
### 2.2 关键代码
|
||||
```java
|
||||
// 关键代码示例
|
||||
public class Example {
|
||||
// 代码实现
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 性能优化
|
||||
|
||||
### 3.1 优化策略
|
||||
- 策略1:说明
|
||||
- 策略2:说明
|
||||
|
||||
### 3.2 调试工具
|
||||
```bash
|
||||
# 调试命令示例
|
||||
adb logcat -s Tag:I
|
||||
```
|
||||
|
||||
## 4. 最佳实践
|
||||
|
||||
### 4.1 设计原则
|
||||
- 原则1:说明
|
||||
- 原则2:说明
|
||||
|
||||
### 4.2 常见问题
|
||||
- 问题1:解决方案
|
||||
- 问题2:解决方案
|
||||
|
||||
## 总结
|
||||
|
||||
[总结文档核心价值和重要性]
|
||||
```
|
||||
|
||||
### 2. 内容质量标准
|
||||
- **专业性**:使用准确的技术术语
|
||||
- **完整性**:覆盖主题的所有重要方面
|
||||
- **实用性**:包含实际代码示例和最佳实践
|
||||
- **可读性**:结构清晰,层次分明
|
||||
- **可维护性**:易于更新和维护
|
||||
|
||||
## 具体操作步骤
|
||||
|
||||
### 步骤1:分析现有文件
|
||||
```powershell
|
||||
# 检查文件状态
|
||||
cd <目录路径>
|
||||
Get-ChildItem "*.md" | Format-Table Name, Length, LastWriteTime
|
||||
|
||||
# 检查文件内容
|
||||
Get-Content <文件名> -TotalCount 5 -Encoding UTF8
|
||||
```
|
||||
|
||||
### 步骤2:处理编码问题
|
||||
```powershell
|
||||
# 如果文件有编码问题,重新创建
|
||||
$content = @'
|
||||
# 文档标题
|
||||
[完整内容]
|
||||
'@
|
||||
|
||||
[System.IO.File]::WriteAllText("<文件名>", $content, [System.Text.Encoding]::UTF8)
|
||||
```
|
||||
|
||||
### 步骤3:完善文档内容
|
||||
|
||||
#### 3.1 基础结构
|
||||
```markdown
|
||||
# 文档标题
|
||||
|
||||
[主题介绍,说明重要性和应用场景]
|
||||
|
||||
## 核心概念
|
||||
[使用列表或表格说明基本概念]
|
||||
|
||||
## 技术实现
|
||||
[详细的技术分析,包含代码示例]
|
||||
|
||||
## 优化策略
|
||||
[性能优化、内存优化等]
|
||||
|
||||
## 调试方法
|
||||
[调试工具和命令]
|
||||
|
||||
## 最佳实践
|
||||
[开发经验和建议]
|
||||
|
||||
## 总结
|
||||
[核心要点总结]
|
||||
```
|
||||
|
||||
#### 3.2 高级结构(适合复杂主题)
|
||||
```markdown
|
||||
# 文档标题
|
||||
|
||||
## 架构概览
|
||||
```mermaid
|
||||
[图表展示整体架构]
|
||||
```
|
||||
|
||||
## 1. 基础原理
|
||||
### 1.1 核心机制
|
||||
### 1.2 关键组件
|
||||
|
||||
## 2. 实现细节
|
||||
### 2.1 代码分析
|
||||
### 2.2 配置说明
|
||||
|
||||
## 3. 性能优化
|
||||
### 3.1 优化方法
|
||||
### 3.2 监控工具
|
||||
|
||||
## 4. 问题排查
|
||||
### 4.1 常见问题
|
||||
### 4.2 解决方案
|
||||
|
||||
## 5. 扩展开发
|
||||
### 5.1 定制化方法
|
||||
### 5.2 集成指南
|
||||
|
||||
## 总结与展望
|
||||
```
|
||||
|
||||
### 步骤4:添加代码示例
|
||||
|
||||
#### 4.1 Java代码示例
|
||||
````markdown
|
||||
```java
|
||||
// 类定义
|
||||
public class Example {
|
||||
private String mData;
|
||||
|
||||
// 方法示例
|
||||
public void doSomething() {
|
||||
// 实现逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
#### 4.2 XML配置示例
|
||||
````markdown
|
||||
```xml
|
||||
<!-- 配置示例 -->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize">
|
||||
</activity>
|
||||
```
|
||||
````
|
||||
|
||||
#### 4.3 Shell命令示例
|
||||
````markdown
|
||||
```bash
|
||||
# 调试命令
|
||||
adb logcat -s ActivityManager:I
|
||||
|
||||
# 性能分析
|
||||
adb shell systrace.py app
|
||||
```
|
||||
````
|
||||
|
||||
### 步骤5:添加图表
|
||||
|
||||
#### 5.1 Mermaid流程图
|
||||
````markdown
|
||||
```mermaid
|
||||
graph TD
|
||||
A[开始] --> B[过程1]
|
||||
B --> C[过程2]
|
||||
C --> D[结束]
|
||||
```
|
||||
````
|
||||
|
||||
#### 5.2 Mermaid序列图
|
||||
````markdown
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant A as 组件A
|
||||
participant B as 组件B
|
||||
A->>B: 请求
|
||||
B-->>A: 响应
|
||||
```
|
||||
````
|
||||
|
||||
#### 5.3 Mermaid状态图
|
||||
````markdown
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> State1
|
||||
State1 --> State2: 事件
|
||||
State2 --> [*]
|
||||
```
|
||||
````
|
||||
|
||||
### 步骤6:验证和测试
|
||||
|
||||
#### 6.1 文件验证
|
||||
```powershell
|
||||
# 验证文件创建
|
||||
if (Test-Path "<文件名>") {
|
||||
$fileInfo = Get-Item "<文件名>"
|
||||
Write-Host "文件大小: $($fileInfo.Length) 字节"
|
||||
|
||||
# 内容验证
|
||||
$content = Get-Content "<文件名>" -TotalCount 3 -Encoding UTF8
|
||||
$content | ForEach-Object { Write-Host $_ }
|
||||
}
|
||||
```
|
||||
|
||||
#### 6.2 编码验证
|
||||
```powershell
|
||||
# 确保UTF-8编码
|
||||
[System.IO.File]::WriteAllText("<文件名>", $content, [System.Text.Encoding]::UTF8)
|
||||
```
|
||||
|
||||
## 具体案例模板
|
||||
|
||||
### 案例:Android组件文档
|
||||
```markdown
|
||||
# [组件名称]深度解析
|
||||
|
||||
[组件介绍和重要性说明]
|
||||
|
||||
## [组件名称]架构概览
|
||||
|
||||
```mermaid
|
||||
[架构图表]
|
||||
```
|
||||
|
||||
## 1. 核心机制
|
||||
|
||||
### 1.1 工作原理
|
||||
- **机制1**:详细说明
|
||||
- **机制2**:详细说明
|
||||
|
||||
### 1.2 生命周期
|
||||
```java
|
||||
// 生命周期方法示例
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// 初始化逻辑
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 配置与使用
|
||||
|
||||
### 2.1 基本配置
|
||||
```xml
|
||||
<!-- 配置示例 -->
|
||||
<component
|
||||
android:name=".ComponentName"
|
||||
android:enabled="true">
|
||||
</component>
|
||||
```
|
||||
|
||||
### 2.2 高级配置
|
||||
[高级配置说明]
|
||||
|
||||
## 3. 性能优化
|
||||
|
||||
### 3.1 内存优化
|
||||
- 策略1:说明
|
||||
- 策略2:说明
|
||||
|
||||
### 3.2 启动优化
|
||||
- 策略1:说明
|
||||
- 策略2:说明
|
||||
|
||||
## 4. 调试与问题排查
|
||||
|
||||
### 4.1 调试工具
|
||||
```bash
|
||||
# 查看组件日志
|
||||
adb logcat -s ComponentTag:I
|
||||
|
||||
# 分析性能
|
||||
adb shell dumpsys <service_name>
|
||||
```
|
||||
|
||||
### 4.2 常见问题
|
||||
- **问题1**:现象和解决方案
|
||||
- **问题2**:现象和解决方案
|
||||
|
||||
## 5. 最佳实践
|
||||
|
||||
### 5.1 设计原则
|
||||
- 原则1:说明
|
||||
- 原则2:说明
|
||||
|
||||
### 5.2 代码规范
|
||||
[代码编写规范]
|
||||
|
||||
## 总结
|
||||
|
||||
[核心价值总结,学习建议]
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
### 1. 编码问题处理
|
||||
- 使用`[System.IO.File]::WriteAllText()`确保UTF-8编码
|
||||
- 避免使用可能引起编码问题的文本编辑器
|
||||
- 验证文件编码是否正确
|
||||
|
||||
### 2. 内容质量控制
|
||||
- 确保技术准确性
|
||||
- 提供实际可用的代码示例
|
||||
- 包含调试和问题排查方法
|
||||
- 遵循Android开发最佳实践
|
||||
|
||||
### 3. 文档维护
|
||||
- 保持文档结构一致性
|
||||
- 定期更新内容
|
||||
- 添加版本更新日志
|
||||
- 提供相关资源链接
|
||||
|
||||
## 自动化脚本模板
|
||||
|
||||
```powershell
|
||||
# 文档完善自动化脚本
|
||||
param(
|
||||
[string]$DirectoryPath,
|
||||
[string]$FileName,
|
||||
[string]$DocumentTitle
|
||||
)
|
||||
|
||||
# 切换到目标目录
|
||||
cd $DirectoryPath
|
||||
|
||||
# 检查文件状态
|
||||
if (Test-Path $FileName) {
|
||||
Write-Host "文件已存在,备份原文件..." -ForegroundColor Yellow
|
||||
$backupName = "$FileName.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||||
Copy-Item $FileName $backupName -Force
|
||||
}
|
||||
|
||||
# 创建文档内容
|
||||
$content = @"
|
||||
# $DocumentTitle
|
||||
|
||||
[文档介绍内容]
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 1. 基本概念
|
||||
- **概念1**:说明
|
||||
- **概念2**:说明
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 2.1 实现机制
|
||||
[技术实现分析]
|
||||
|
||||
### 2.2 代码示例
|
||||
\`\`\`java
|
||||
// 示例代码
|
||||
public class Example {
|
||||
// 实现
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 3.1 开发建议
|
||||
- 建议1
|
||||
- 建议2
|
||||
|
||||
## 总结
|
||||
|
||||
[文档总结]
|
||||
"@
|
||||
|
||||
# 保存文档
|
||||
try {
|
||||
[System.IO.File]::WriteAllText($FileName, $content, [System.Text.Encoding]::UTF8)
|
||||
Write-Host "文档创建成功: $FileName" -ForegroundColor Green
|
||||
|
||||
# 验证
|
||||
if (Test-Path $FileName) {
|
||||
$size = (Get-Item $FileName).Length
|
||||
Write-Host "文件大小: $size 字节" -ForegroundColor Green
|
||||
}
|
||||
} catch {
|
||||
Write-Host "文档创建失败: $_" -ForegroundColor Red
|
||||
}
|
||||
```
|
||||
|
||||
## 使用建议
|
||||
|
||||
1. **根据文档类型选择模板**:简单主题使用基础结构,复杂主题使用高级结构
|
||||
2. **确保技术准确性**:所有技术内容必须准确无误
|
||||
3. **提供实用价值**:文档应该对开发者有实际帮助
|
||||
4. **保持一致性**:同一项目的文档保持相同风格和结构
|
||||
5. **定期更新**:随着技术发展更新文档内容
|
||||
|
||||
通过遵循这个模板,可以高效地创建和完善Android Framework相关文档,确保文档质量和技术价值。
|
||||
Reference in New Issue
Block a user