# 全局心跳机制实现说明

## 问题描述
网口连接后，在TextPrintActivity页面发送数据开始能正常打印，但等待3-5分钟后再次发送就失败，没有反应。

## 根本原因
TCP Socket连接在空闲状态下会被以下原因断开：
1. 路由器/NAT设备的TCP连接超时清理（通常3-5分钟）
2. 打印机端的空闲连接超时设置
3. Android系统的网络策略

原代码中SDK的`PrinterInstance`类没有实现心跳保活机制，导致连接断开后`isConnected`标志仍为true，发送数据时才发现问题。

## 解决方案
实现全局应用层心跳机制（方案3），在DemoApplication中添加定时心跳服务，对所有页面生效。

## 实现细节

### 1. DemoApplication.java - 心跳核心实现
**文件位置**: `PrintDemoV5.7.1/src/main/java/com/printer/wifidemo/DemoApplication.java`

**新增功能**:
- `startGlobalHeartbeat()`: 启动全局心跳服务
  - 每20秒发送一次心跳包（ESC @ 复位指令）
  - 自动检测连接状态，发送失败时更新全局连接标志
  - 使用ScheduledExecutorService实现定时任务

- `stopGlobalHeartbeat()`: 停止全局心跳服务
  - 在断开连接或应用退出时调用
  - 释放线程资源

**心跳指令**: `0x1B 0x40` (ESC @)
- 这是打印机复位指令，不会影响当前打印状态
- 仅用于保持TCP连接活跃

### 2. SimpleConnectActivity.java - 主要连接管理
**修改位置**: Handler消息处理

**启动心跳**:
- `Connect.SUCCESS`: 连接成功时启动心跳
- WiFi自动连接的独立Handler中也添加了启动逻辑

**停止心跳**:
- `Connect.FAILED`: 连接失败时停止
- `Connect.CLOSED`: 连接关闭时停止
- `disconnectPrinter()`: 手动断开时停止

### 3. MainActivity.java - 主界面连接管理
**修改位置**: 
- `disconnectPrinter()`: 手动断开连接时停止心跳
- USB断开广播接收器: USB设备移除时停止心跳

### 4. SettingActivity.java - 设置页面连接管理
**修改位置**:
- Handler的`Connect.SUCCESS`: 连接成功时启动心跳
- Handler的`Connect.CLOSED`: 连接关闭时停止心跳
- 按钮点击断开连接时停止心跳
- 打印自检页后断开连接时停止心跳

## 技术要点

### 心跳间隔设置
```java
private static final long HEARTBEAT_INTERVAL = 20; // 20秒
```
- 选择20秒是因为大多数路由器的TCP超时时间在60-300秒之间
- 20秒足够频繁以保持连接活跃
- 不会对网络造成明显负担

### 异常处理
心跳服务包含完善的异常处理：
1. 发送失败时自动更新连接状态
2. 捕获所有异常防止崩溃
3. 记录详细日志便于调试

### 线程安全
- 使用`ScheduledExecutorService`确保单线程执行
- 启动前先停止旧的心跳服务，避免重复
- 使用`shutdownNow()`立即停止线程

## 测试建议

### 1. 基本功能测试
1. 通过WiFi连接打印机
2. 在TextPrintActivity发送打印数据，确认正常
3. 等待5分钟不操作
4. 再次发送打印数据，应该仍然正常

### 2. 日志验证
查看Logcat中的心跳日志：
```
GlobalHeartbeat: Global heartbeat started, interval: 20s
GlobalHeartbeat: Heartbeat sent successfully
GlobalHeartbeat: Heartbeat sent successfully
...
```

### 3. 断开重连测试
1. 连接打印机后，观察心跳日志
2. 手动断开连接，应看到"Global heartbeat stopped"
3. 重新连接，应看到新的"Global heartbeat started"

### 4. 异常情况测试
1. 连接后关闭打印机电源
2. 观察是否在下次心跳时检测到连接断开
3. 检查UI是否正确显示离线状态

## 注意事项

1. **内存泄漏防护**: 
   - 在Activity/Fragment销毁时确保停止心跳
   - 已在所有断开连接的地方添加停止逻辑

2. **多页面共享**:
   - 心跳服务是全局单例，所有页面共享
   - 避免多个页面同时启动多个心跳任务

3. **蓝牙连接**:
   - 当前心跳对蓝牙连接也有效
   - 蓝牙通常不需要心跳，但不会影响

4. **性能影响**:
   - 每20秒发送2字节数据，几乎无性能影响
   - 使用单线程，资源占用极小

## 相关文件清单

修改的文件：
1. `DemoApplication.java` - 添加心跳核心功能
2. `SimpleConnectActivity.java` - 添加心跳启停控制
3. `MainActivity.java` - 添加心跳启停控制
4. `SettingActivity.java` - 添加心跳启停控制

未修改但受益的文件：
- `TextPrintActivity.java` - 无需修改，自动享受心跳保护
- `BarcoePrintActivity.java` - 无需修改，自动享受心跳保护
- `PdfPrintActivity.java` - 无需修改，自动享受心跳保护
- 所有其他打印相关Activity

## 后续优化建议

1. **可配置心跳间隔**: 
   - 在设置页面添加心跳间隔配置选项
   - 允许用户根据网络环境调整

2. **智能心跳**:
   - 检测到有打印任务时提高心跳频率
   - 空闲时降低心跳频率

3. **连接质量监控**:
   - 统计心跳失败次数
   - 连续失败多次后提示用户检查网络

4. **重连机制**:
   - 心跳检测到断开时自动尝试重连
   - 提供自动重连开关
