// ============================================================ // 闲言APP — 应用入口 // 创建时间: 2026-04-20 /// 更新时间: 2026-06-05 /// 作用: main 函数,初始化存储 + 液态玻璃 + 异常捕获 + 启动 App /// 上次更新: 新增PlatformCapabilities.init()平台能力注册表初始化 // ============================================================ import 'dart:async'; import 'dart:isolate' if (dart.library.js) 'core/utils/platform/isolate_stub.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:liquid_glass_widgets/liquid_glass_widgets.dart'; import 'package:flutter/services.dart'; import 'package:window_manager/window_manager.dart'; import 'app/app.dart'; import 'core/constants/app_constants.dart'; import 'core/services/network/deep_link_service.dart'; import 'core/services/performance/performance_orchestrator.dart'; import 'core/services/error/crash_monitor.dart'; import 'core/services/device/haptic_service.dart'; import 'core/storage/kv_storage.dart'; import 'core/services/error/global_error_handler.dart'; import 'core/services/post_agreement_initializer.dart'; import 'core/utils/logger.dart' show Log, LogCategory; import 'core/utils/platform/platform_utils.dart' as pu; import 'core/utils/platform/platform_capability.dart'; import 'core/registry/page_registry.dart'; import 'core/router/app_router.dart'; import 'core/services/catcher2_config_service.dart'; import 'editor/services/3d/platform_3d_service.dart'; import 'features/template/services/wallpaper_favorite_service.dart'; import 'features/template/services/wallpaper_health_service.dart'; import 'features/mine/settings/services/settings_change_logger.dart'; import 'features/discover/services/rss_service.dart'; import 'features/discover/services/exchange_rate_service.dart'; bool kvStorageReady = false; bool _liquidGlassReady = false; bool get liquidGlassReady => _liquidGlassReady; void main() async { // Catcher2 内部会调用 runZonedGuarded 并在其中执行 runApp, // 因此 binding 必须在 Catcher2 之前初始化(在同一个 root zone), // 否则会出现 Zone mismatch 警告。 WidgetsFlutterBinding.ensureInitialized(); // 移除外层 runZonedGuarded,由 Catcher2 内部管理 zone // 异常捕获由 Catcher2 + GlobalErrorHandler 共同处理 _appMain().catchError((Object e, StackTrace st) { Log.e('main初始化失败', e, st, LogCategory.general); }); } /// 应用主入口逻辑 Future _appMain() async { if (pu.isDesktop) { await windowManager.ensureInitialized(); const windowOptions = WindowOptions( minimumSize: Size(400, 600), title: '闲言', center: true, ); await windowManager.waitUntilReadyToShow(windowOptions, () async { await windowManager.show(); }); } if (pu.isOhos) Log.i('🟢 [OHOS] main() 开始执行', null, null, LogCategory.general); // 初始化平台能力注册表(必须在其他服务初始化之前) PlatformCapabilities.init(); Log.i('平台能力注册表初始化完成', null, null, LogCategory.general); FlutterError.onError = (FlutterErrorDetails details) { final msg = details.exceptionAsString(); // 布局溢出等非致命错误:仅打印日志,不弹窗/不显示溢出指示器 if (msg.contains('overflowed')) { Log.w( '⚠️ FlutterError: RenderFlex overflow (已静默)', msg, details.stack, LogCategory.general, ); return; } FlutterError.presentError(details); Log.e( '🔥 FlutterError.onError', details.exceptionAsString(), details.stack, LogCategory.general, ); }; GlobalErrorHandler.init(); if (!pu.isWeb) { Isolate.current.addErrorListener( RawReceivePort((Object? pair) { final List errorAndStacktrace = pair as List; Log.e( '🔥 Isolate uncaught error', errorAndStacktrace.first, StackTrace.fromString(errorAndStacktrace.last.toString()), LogCategory.general, ); }).sendPort, ); } if (!pu.isWeb) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); } if (pu.isOhos) Log.i('🟢 [OHOS] SystemChrome 配置完成', null, null, LogCategory.general); try { await AppVersion.init(); Log.i('AppVersion 初始化完成', null, null, LogCategory.general); } catch (e, st) { Log.e('AppVersion 初始化失败', e, st, LogCategory.general); } try { await KvStorage.init(); kvStorageReady = true; if (pu.isOhos) Log.i('🟢 [OHOS] KvStorage 初始化完成', null, null, LogCategory.storage); } catch (e, st) { Log.e('KV 存储初始化失败', e, st, LogCategory.storage); } try { await HapticService.init(); Log.i('触觉反馈服务初始化完成', null, null, LogCategory.haptic); } catch (e, st) { Log.e('触觉反馈服务初始化失败', e, st, LogCategory.haptic); } try { await WallpaperFavoriteService.init(); Log.i('壁纸收藏服务初始化完成', null, null, LogCategory.general); } catch (e, st) { Log.e('壁纸收藏服务初始化失败', e, st, LogCategory.general); } try { PerformanceOrchestrator.instance.init(); Log.i('PerformanceOrchestrator 初始化完成', null, null, LogCategory.service); } catch (e, st) { Log.e('PerformanceOrchestrator 初始化失败', e, st, LogCategory.service); } try { await LiquidGlassWidgets.initialize(); _liquidGlassReady = true; Log.i('LiquidGlassWidgets 初始化完成 (ohos=${pu.isOhos})', null, null, LogCategory.ui); } catch (e, st) { Log.e('LiquidGlassWidgets 初始化失败', e, st, LogCategory.ui); } try { await Platform3DService.instance.detectDeviceCapability(); if (pu.isOhos) Log.i( '🟢 [OHOS] 3D设备检测完成 (lowEnd=${Platform3DService.instance.isLowEnd})', null, null, LogCategory.device, ); } catch (e, st) { Log.e('3D平台设备检测失败', e, st, LogCategory.device); } try { _validatePageRegistry(); } catch (e, st) { Log.e('页面注册表验证失败', e, st, LogCategory.general); } if (!pu.isWeb) { try { await DeepLinkService.init(); if (pu.isOhos) Log.i('🟢 [OHOS] 深度链接服务初始化完成', null, null, LogCategory.router); } catch (e, st) { Log.e('深度链接服务初始化失败', e, st, LogCategory.router); } } try { await CrashMonitor.instance.init(); Log.i('崩溃监控服务初始化完成', null, null, LogCategory.service); } catch (e, st) { Log.e('崩溃监控服务初始化失败', e, st, LogCategory.service); } try { await WallpaperHealthService.init(); Log.i('壁纸源健康检测服务初始化完成', null, null, LogCategory.service); } catch (e, st) { Log.e('壁纸源健康检测服务初始化失败', e, st, LogCategory.service); } try { await SettingsChangeLogger.init(); Log.i('设置变更日志服务初始化完成', null, null, LogCategory.service); } catch (e, st) { Log.e('设置变更日志服务初始化失败', e, st, LogCategory.service); } try { await RssService.init(); Log.i('RSS服务初始化完成', null, null, LogCategory.network); } catch (e, st) { Log.e('RSS服务初始化失败', e, st, LogCategory.network); } try { await ExchangeRateService.init(); Log.i('汇率缓存服务初始化完成', null, null, LogCategory.network); } catch (e, st) { Log.e('汇率缓存服务初始化失败', e, st, LogCategory.network); } if (PostAgreementInitializer.shouldInit()) { Log.i('检测到老用户已完成引导,立即初始化权限敏感服务', null, null, LogCategory.general); try { await PostAgreementInitializer.init(); } catch (e, st) { Log.e('老用户权限敏感服务初始化失败', e, st, LogCategory.general); } } else { Log.i('新用户未同意协议,权限敏感服务延迟到协议同意后初始化', null, null, LogCategory.onboarding); } // 初始化 Catcher2 异常捕获并启动应用 // 使用 rootWidget 方式,Catcher2 内部调用 runApp,避免 Zone mismatch if (_liquidGlassReady) { Catcher2ConfigService.instance.init( rootWidget: LiquidGlassWidgets.wrap( child: const ProviderScope(child: XianyanApp()), ), ); } else { Catcher2ConfigService.instance.init( rootWidget: const ProviderScope(child: XianyanApp()), ); } if (pu.isOhos) { Log.i('🟢 [OHOS] runApp() 已调用', null, null, LogCategory.general); } } void _validatePageRegistry() { final errors = PageRegistry.validateAll(); if (errors.isNotEmpty) { for (final e in errors) { Log.e('页面注册表验证失败: $e', null, null, LogCategory.general); } } else { Log.i('页面注册表验证通过,共 ${PageRegistry.pageCount} 个页面已注册', null, null, LogCategory.general); } const route = AppRoutes.home; if (!PageRegistry.isRouteRegistered(route)) { Log.e('页面注册表验证: 首页路由 $route 未注册!', null, null, LogCategory.general); } }