main.dart 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import 'package:firebase_core/firebase_core.dart';
  2. import 'package:firebase_crashlytics/firebase_crashlytics.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/services.dart';
  6. import 'package:flutter_riverpod/flutter_riverpod.dart';
  7. import 'package:flutter_secure_storage/flutter_secure_storage.dart';
  8. import 'package:hive_flutter/hive_flutter.dart';
  9. import 'package:shared_preferences/shared_preferences.dart';
  10. import 'app.dart';
  11. import 'firebase_options.dart';
  12. import 'providers/app_provider.dart';
  13. Future<void> main() async {
  14. WidgetsFlutterBinding.ensureInitialized();
  15. // 捕获所有 Dart 异常
  16. FlutterError.onError = (FlutterErrorDetails details) {
  17. // 布局溢出(RenderFlex overflow)是 debug 模式下的警告,不属于崩溃,不上报
  18. final summary = details.exception.toString();
  19. if (summary.contains('RenderFlex overflowed') || summary.contains('overflowed by')) {
  20. if (kDebugMode) FlutterError.dumpErrorToConsole(details, forceReport: false);
  21. return;
  22. }
  23. FlutterError.dumpErrorToConsole(details);
  24. FirebaseCrashlytics.instance.recordFlutterFatalError(details);
  25. };
  26. // 捕获异步异常(Platform/isolate)
  27. PlatformDispatcher.instance.onError = (error, stack) {
  28. // Flutter SDK / Dart VM 已知 bug:WS 重连时 _SocketProfile.collectStatistic assertion 失败
  29. final msg = error.toString();
  30. if (msg.contains('_SocketProfile') || msg.contains('network_profiling')) {
  31. return true;
  32. }
  33. FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
  34. return true;
  35. };
  36. try {
  37. // 强制竖屏
  38. await SystemChrome.setPreferredOrientations([
  39. DeviceOrientation.portraitUp,
  40. DeviceOrientation.portraitDown,
  41. ]);
  42. // 状态栏透明
  43. SystemChrome.setSystemUIOverlayStyle(
  44. const SystemUiOverlayStyle(
  45. statusBarColor: Colors.transparent,
  46. ),
  47. );
  48. // Hive 初始化
  49. await Hive.initFlutter();
  50. // SharedPreferences 初始化
  51. final prefs = await SharedPreferences.getInstance();
  52. // 重装检测:iOS Keychain 卸载后不会自动清除,需手动处理
  53. // SharedPreferences 卸载后会被系统清除,利用此差异检测重装
  54. const kAppInstalled = 'app_installed';
  55. if (!(prefs.getBool(kAppInstalled) ?? false)) {
  56. await const FlutterSecureStorage().deleteAll();
  57. await prefs.setBool(kAppInstalled, true);
  58. }
  59. // Firebase 初始化 - 后台异步执行,不阻塞 runApp
  60. Firebase.initializeApp(
  61. options: DefaultFirebaseOptions.currentPlatform,
  62. ).then((_) async {
  63. // Debug 模式下关闭 Crashlytics 上报,避免污染生产数据
  64. await FirebaseCrashlytics.instance
  65. .setCrashlyticsCollectionEnabled(!kDebugMode);
  66. });
  67. runApp(
  68. ProviderScope(
  69. overrides: [
  70. sharedPreferencesProvider.overrideWithValue(prefs),
  71. ],
  72. child: const CexApp(),
  73. ),
  74. );
  75. } catch (e, stack) {
  76. debugPrint('🔴 [main] 初始化失败: $e\n$stack');
  77. rethrow;
  78. }
  79. }