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

8.9 KiB
Raw Blame History

🔥 卡死/闪退问题分析与修复记录

文档创建: 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,但 mealRecordslate 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. _cacheOptionslate 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.isIOSPlatform.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. 用户感觉"卡死"
  • 修复方案:
    • 短期: 当前数据量不大,影响可忽略
    • 长期: 改为 computeIsolate 执行重计算
  • 修复日期: 2026-04-09标记为低优先级暂不需要 Isolate

🟡 低危问题(边界情况)

#8 SharedPreferences 初始化前访问

  • 状态: 已修复
  • 优先级: P3
  • 文件: lib/src/services/data/storage_service.dart
  • 触发路径:
    1. _prefslate 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 CacheOptionsCacheOptions?
    • 添加 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 SharedPreferencesSharedPreferences?
    • 读取用 ?. 安全调用,写入加 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 / 变量 / 不必要的 ! / 死代码