Files
kitchen/docs/dev/CRASH_FIX_LOG.md
Developer 8d27c67d3a api实现
2026-04-09 08:54:36 +08:00

260 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🔥 卡死/闪退问题分析与修复记录
> 文档创建: 2026-04-09
> 最后更新: 2026-04-09
> 维护者: 前端工程师
> 说明: 记录项目中所有可能导致应用卡死、闪退的潜在问题,跟踪修复进度
---
## 📊 问题总览
| 等级 | 数量 | 已修复 | 待修复 |
|------|------|--------|--------|
| 🔴 高危 | 4 | 4 | 0 |
| 🟠 中危 | 3 | 3 | 0 |
| 🟡 低危 | 4 | 3 | 1 |
| **合计** | **11** | **10** | **1** |
---
## 🔴 高危问题(直接导致闪退)
### #1 Hive `late` Box 未初始化访问
- **状态**: ✅ 已修复
- **优先级**: P0
- **文件**: `lib/src/services/data/hive_service.dart`
- **触发路径**:
1. `MealRecordController.onInit()``_loadDayRecords()``HiveService().getMealRecordsByDate()`
2. `getMealRecordsByDate()` 访问 `mealRecords.values`,但 `mealRecords``late Box`
3. 如果 `HiveService.init()` 尚未完成,`late` 字段未赋值 → `LateInitializationError` → 闪退
- **修复方案**:
- `late Box` 改为 `Box?` 可空类型
- 所有 getter 加 `_assertInitialized()` 检查
- Controller 中所有 Hive 读取操作前加 `if (!hive.isInitialized) return;`
- **修复日期**: 2026-04-09
---
### #2 ApiService 缓存竞态条件
- **状态**: ✅ 已修复
- **优先级**: P0
- **文件**: `lib/src/services/api/api_service.dart`
- **触发路径**:
1. `ApiService._internal()` 构造函数中调用 `_initCacheAsync()` (fire-and-forget)
2. `_cacheOptions``late CacheOptions`,在 `_initCacheAsync()` 完成前未赋值
3. 如果首次网络请求在缓存初始化完成前发起 → 访问未初始化的 `late` 字段 → 闪退
- **修复方案**:
- `late CacheOptions` 改为 `CacheOptions?`
- 添加 `Completer<void>` 跟踪初始化状态
- `_ensureCacheReady()` 等待 Completer 完成
- `_tryGetCache()` 加 null 检查
- **修复日期**: 2026-04-09
---
### #3 Get.find 未注册 Controller 闪退
- **状态**: ✅ 已修复
- **优先级**: P1
- **文件**: `lib/src/controllers/what_to_eat_controller.dart`
- **触发路径**:
1. `_fetchSmartWithPreferences()` 中调用 `Get.find<PreferenceController>()`
2. 如果 `PreferenceController` 未被 `Get.put` 注册 → 抛出异常 → 闪退
- **修复方案**: 使用 `Get.isRegistered<T>()` 先判断再 `find`
- **修复日期**: 2026-04-09
---
### #4 Platform API 在 Web 平台崩溃
- **状态**: ✅ 已修复
- **优先级**: P1
- **文件**: `lib/src/utils/platform_utils.dart`
- **触发路径**:
1. 直接使用 `Platform.isIOS``Platform.isAndroid`
2. 在 Web 平台调用 → `UnsupportedError` → 闪退
- **修复方案**:
- 使用条件导入 `import 'dart:io' if (dart.library.html) 'platform_web_stub.dart'`
- 所有 `Platform.*` 调用前加 `if (kIsWeb) return false;`
- 创建 `platform_web_stub.dart` 提供 Web 平台 stub
- **修复日期**: 2026-04-09
---
## 🟠 中危问题(可能导致卡死)
### #5 网络请求无超时兜底
- **状态**: ✅ 已修复
- **优先级**: P2
- **文件**: `lib/src/services/api/api_service.dart`
- **触发路径**:
1. `_isOffline()` 调用 `Connectivity().checkConnectivity()`
2. 该方法本身可能卡住(如网络权限未授予)
3. 虽然 Dio 设置了 10s 超时,但连接性检查无超时
- **修复方案**: 给 `_isOffline()``.timeout(Duration(seconds: 3))` 限制,超时默认视为离线
- **修复日期**: 2026-04-09
---
### #6 `runWithLoading` 嵌套调用状态错乱
- **状态**: ✅ 已修复
- **优先级**: P2
- **文件**: `lib/src/controllers/base/base_controller.dart`
- **触发路径**:
1. `isLoading` 是单一 `RxBool`
2. 如果外层 `runWithLoading` 内部又调用 `runWithLoading`
3. 内层完成后 `isLoading = false`,但外层仍在执行
4. UI 显示加载完成,但数据可能不完整 → 用户操作异常
- **修复方案**: 使用计数器 `_loadingCount` 替代布尔值,仅当计数归零时设 `isLoading = false`
- **修复日期**: 2026-04-09
---
### #7 Hive Box 同步操作阻塞主线程
- **状态**: ✅ 已修复(低优先级标记)
- **优先级**: P3
- **文件**: `lib/src/services/data/hive_service.dart`
- **触发路径**:
1. `getMealRecordsByDate()``getWeeklyCalories()` 等同步遍历 Box
2. 数据量大时(如数百条记录)阻塞 UI 线程
3. 用户感觉"卡死"
- **修复方案**:
- 短期: 当前数据量不大,影响可忽略
- 长期: 改为 `compute``Isolate` 执行重计算
- **修复日期**: 2026-04-09标记为低优先级暂不需要 Isolate
---
## 🟡 低危问题(边界情况)
### #8 SharedPreferences 初始化前访问
- **状态**: ✅ 已修复
- **优先级**: P3
- **文件**: `lib/src/services/data/storage_service.dart`
- **触发路径**:
1. `_prefs``late SharedPreferences`
2. 如果 `init()` 未完成就调用 `getString()` 等 → `LateInitializationError`
- **修复方案**:
- `late SharedPreferences` 改为 `SharedPreferences?`
- 添加 `isInitialized` 标志
- 读取方法用 `_prefs?.` 安全调用,返回 null
- 写入方法加 `if (_prefs == null) return;` 静默跳过
- **修复日期**: 2026-04-09
---
### #9 LoggerService 初始化前写日志
- **状态**: ✅ 已修复
- **优先级**: P3
- **文件**: `lib/src/services/log/logger_service.dart`
- **修复内容**: `_logger` 改为 `Logger?`,所有调用处加 null 检查,降级到 `debugPrint`
- **修复日期**: 2026-04-09
---
### #10 PageRoute 中间件拦截循环
- **状态**: ✅ 已修复
- **优先级**: P3
- **文件**: `lib/src/standards/route_middleware.dart`
- **触发路径**:
1. 如果 `/standards-violation` 页面自身也校验失败
2. 中间件再次重定向到 `/standards-violation` → 无限循环
- **修复方案**: 对 `/standards-violation` 路由跳过校验,直接 `return null`
- **修复日期**: 2026-04-09
---
### #11 MediaQuery 在 Context 不完整时崩溃
- **状态**: ✅ 已修复
- **优先级**: P0
- **文件**: `lib/src/standards/page_standards.dart`
- **修复内容**: 所有 `MediaQuery.of(context)` 调用加 `try-catch`,降级到默认值
- **修复日期**: 2026-04-09
---
## 📋 修复进度
| # | 问题 | 优先级 | 状态 | 修复日期 |
|---|------|--------|------|----------|
| 1 | Hive late Box 未初始化 | P0 | ✅ 已修复 | 2026-04-09 |
| 2 | ApiService 缓存竞态 | P0 | ✅ 已修复 | 2026-04-09 |
| 3 | Get.find 未注册 Controller | P1 | ✅ 已修复 | 2026-04-09 |
| 4 | Platform API Web 崩溃 | P1 | ✅ 已修复 | 2026-04-09 |
| 5 | 网络请求无超时兜底 | P2 | ✅ 已修复 | 2026-04-09 |
| 6 | runWithLoading 嵌套 | P2 | ✅ 已修复 | 2026-04-09 |
| 7 | Hive 同步操作阻塞 | P3 | ✅ 标记低优 | 2026-04-09 |
| 8 | SharedPreferences 未初始化 | P3 | ✅ 已修复 | 2026-04-09 |
| 9 | LoggerService 未初始化 | P3 | ✅ 已修复 | 2026-04-09 |
| 10 | 中间件拦截循环 | P3 | ✅ 已修复 | 2026-04-09 |
| 11 | MediaQuery 空值崩溃 | P0 | ✅ 已修复 | 2026-04-09 |
---
## 🔧 修复详情
### 2026-04-09 修复批次(第二轮)
1. **Hive late Box 未初始化** (#1)
- `late Box<T>``Box<T>?`getter 加 `_assertInitialized()`
- `MealRecordController` 所有 Hive 读取加 `if (!hive.isInitialized) return;`
2. **ApiService 缓存竞态** (#2)
- `late CacheOptions``CacheOptions?`
- 添加 `Completer<void>` 跟踪初始化
- `_ensureCacheReady()` 等待 Completer
- `_tryGetCache()` 加 null 检查
3. **Get.find 未注册 Controller** (#3)
- `Get.find<T>()` 前加 `Get.isRegistered<T>()` 判断
4. **Platform API Web 崩溃** (#4)
- 条件导入 `dart:io if (dart.library.html)`
- 所有 `Platform.*` 调用前加 `kIsWeb` 检查
- 创建 `platform_web_stub.dart`
5. **网络请求超时兜底** (#5)
- `_isOffline()``.timeout(Duration(seconds: 3))`
- 超时默认视为离线
6. **runWithLoading 嵌套** (#6)
- `RxBool` → 计数器 `_loadingCount`
- 仅当计数归零时设 `isLoading = false`
7. **SharedPreferences 未初始化** (#8)
- `late SharedPreferences``SharedPreferences?`
- 读取用 `?.` 安全调用,写入加 null 检查
8. **中间件拦截循环** (#10)
- `/standards-violation` 路由跳过校验
### 2026-04-09 修复批次(第一轮)
1. **LoggerService 空值崩溃** (#9, #11 相关)
- `_logger` 改为 `Logger?`,所有方法加 null 检查
- `dispose()` 改为 `_logger?.close()`
2. **PageStandards MediaQuery 空值崩溃** (#11)
- 所有 `MediaQuery.of(context)` 加 try-catch
- 降级到安全默认值 (375×812, 44/34 padding)
- `l10n` 改为可空 `AppLocalizations?`
3. **l10n 可空类型连锁修复**
- `empty_state.dart`: `l10n?.noData ?? '暂无数据'`
- `error_state.dart`: `l10n?.retry ?? '重试'`
- `standard_dialog.dart`: 6处 `l10n?.confirm/cancel` 加降级中文
- `page_validator.dart`: `l10n?.appTitle.isNotEmpty ?? false`
4. **代码警告清理** (15项)
- 移除未使用的 import / 变量 / 不必要的 `!` / 死代码