# 功耗优化工具链

## 概述

功耗优化是移动应用开发中的重要环节，直接影响用户体验和设备续航。本文档介绍Android功耗优化的工具链、分析方法和优化策略。

## 功耗分析工具

### 1. Battery Historian

Google官方提供的功耗分析工具，可以分析设备的电量消耗情况。

#### 安装与使用

```bash
# 安装Battery Historian
go get -u github.com/google/battery-historian

# 启动服务
cd $GOPATH/src/github.com/google/battery-historian
go run cmd/battery-historian/battery-historian.go
```

#### 数据采集

```bash
# 重置电池统计
adb shell dumpsys batterystats --reset

# 执行测试场景
# ... 进行应用操作 ...

# 导出数据
adb bugreport > bugreport.txt
```

#### 关键指标

- **Wake Lock**: 唤醒锁持有时间
- **CPU**: CPU使用率
- **Network**: 网络流量
- **GPS**: GPS使用情况
- **Screen**: 屏幕亮度与唤醒时间

### 2. Android Profiler

Android Studio内置的性能分析工具，可以实时监控功耗。

#### 使用步骤

1. 连接设备
2. 打开Android Profiler
3. 选择Energy标签
4. 监控电量消耗

#### 功能特点

- 实时监控
- 可视化展示
- 支持录制和回放

### 3. dumpsys batterystats

系统命令，可以获取详细的电池统计信息。

```bash
# 查看电池统计
adb shell dumpsys batterystats

# 查看特定应用的功耗
adb shell dumpsys batterystats com.example.app

# 重置统计
adb shell dumpsys batterystats --reset
```

### 4. Power Monitor

硬件级功耗监控工具，需要支持Power Monitor的设备。

## 功耗优化策略

### 1. CPU优化

#### 减少CPU唤醒

```java
// 避免频繁唤醒CPU
// 使用JobScheduler替代AlarmManager
JobScheduler jobScheduler = 
    (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(this, MyJobService.class))
    .setPeriodic(15 * 60 * 1000) // 15分钟
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
    .build();
jobScheduler.schedule(jobInfo);
```

#### 优化算法复杂度

- 使用高效的数据结构
- 避免不必要的循环
- 使用缓存减少计算

#### 后台任务优化

```java
// 使用WorkManager管理后台任务
WorkRequest uploadWork = new OneTimeWorkRequest.Builder(UploadWorker.class)
    .setConstraints(new Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .setRequiresCharging(true)
        .build())
    .build();
WorkManager.getInstance(context).enqueue(uploadWork);
```

### 2. 网络优化

#### 批量请求

```java
// 合并多个小请求为一个批量请求
// 减少网络唤醒次数
```

#### 使用缓存

```java
// 使用HTTP缓存减少网络请求
CacheControl cacheControl = new CacheControl.Builder()
    .maxAge(1, TimeUnit.HOURS)
    .build();
```

#### 压缩数据

```java
// 使用Gzip压缩
// 减少传输数据量
```

### 3. Wake Lock管理

#### 及时释放Wake Lock

```java
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(
    PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag");
    
try {
    wakeLock.acquire();
    // 执行需要保持唤醒的操作
} finally {
    if (wakeLock.isHeld()) {
        wakeLock.release();
    }
}
```

#### 使用超时机制

```java
// 设置超时，避免长时间持有
wakeLock.acquire(10 * 60 * 1000L); // 10分钟超时
```

### 4. 定位服务优化

#### 使用低功耗定位

```java
LocationRequest locationRequest = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_LOW_POWER)
    .setInterval(60000) // 1分钟
    .setMaxWaitTime(5 * 60 * 1000); // 5分钟最大等待
```

#### 及时停止定位

```java
// 不需要定位时立即停止
locationManager.removeUpdates(locationListener);
```

### 5. 屏幕优化

#### 降低屏幕亮度

```java
// 根据环境光自动调整
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 0.5f; // 50%亮度
getWindow().setAttributes(params);
```

#### 减少屏幕唤醒时间

```java
// 设置屏幕超时时间
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// 使用后及时清除
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
```

### 6. 后台任务优化

#### 使用Doze模式

```java
// 适配Doze模式
// 使用白名单机制
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean isIgnoringBatteryOptimizations = 
    powerManager.isIgnoringBatteryOptimizations(getPackageName());
    
if (!isIgnoringBatteryOptimizations) {
    Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivity(intent);
}
```

#### 延迟非紧急任务

```java
// 使用JobScheduler延迟执行
JobInfo jobInfo = new JobInfo.Builder(1, componentName)
    .setMinimumLatency(30 * 60 * 1000) // 延迟30分钟
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
    .build();
```

## 功耗测试方法

### 1. 基准测试

```bash
# 1. 重置电池统计
adb shell dumpsys batterystats --reset

# 2. 执行测试场景（30分钟）
# 模拟用户正常使用

# 3. 导出数据
adb bugreport > bugreport.txt

# 4. 分析Battery Historian报告
```

### 2. 对比测试

- 优化前后对比
- 竞品对比
- 不同设备对比

### 3. 场景测试

- 待机场景
- 使用场景
- 后台场景

## 常见问题

### 1. Wake Lock泄漏

**症状**: 设备无法进入休眠

**排查**:
```bash
adb shell dumpsys power
```

**解决**: 检查所有Wake Lock的acquire/release配对

### 2. 后台网络请求过多

**症状**: 待机时仍有网络流量

**排查**: Battery Historian查看Network统计

**解决**: 使用JobScheduler批量处理

### 3. GPS持续定位

**症状**: 定位服务一直运行

**排查**: Battery Historian查看GPS统计

**解决**: 及时停止定位服务

## 最佳实践

1. **最小化原则**: 只做必要的工作
2. **批量处理**: 合并多个小任务
3. **延迟执行**: 非紧急任务延迟处理
4. **及时释放**: 用完资源立即释放
5. **监控告警**: 建立功耗监控体系

## 相关链接

- [[README]]
- [[启动优化方法论]]
- [[09-调试与工具链/Systrace_Perfetto全解读]]
