import 'dart:async'; import 'dart:io'; import 'dart:ui'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:fluro/fluro.dart' as fluro; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:yumi/shared/tools/sc_keybord_util.dart'; import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart'; import 'package:provider/provider.dart'; import 'package:provider/single_child_widget.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'app_localizations.dart'; import 'app/config/app_config.dart'; import 'app/constants/sc_global_config.dart'; import 'app/constants/sc_screen.dart'; import 'app/routes/sc_routes.dart'; import 'app/routes/sc_lk_application.dart'; import 'shared/tools/sc_deep_link_handler.dart'; import 'shared/tools/sc_deviceId_utils.dart'; import 'modules/splash/splash_page.dart'; import 'services/general/sc_app_general_manager.dart'; import 'services/payment/apple_payment_manager.dart'; import 'services/auth/authentication_manager.dart'; import 'services/gift/gift_animation_manager.dart'; import 'services/gift/gift_system_manager.dart'; import 'services/payment/google_payment_manager.dart'; import 'services/localization/localization_manager.dart'; import 'services/room/rc_room_manager.dart'; import 'services/audio/rtc_manager.dart'; import 'services/audio/rtm_manager.dart'; import 'services/shop/shop_manager.dart'; import 'services/theme/theme_manager.dart'; import 'services/auth/user_profile_manager.dart'; import 'ui_kit/theme/socialchat_theme.dart'; import 'ui_kit/widgets/room/effect/vapp_svga_layer_widget.dart'; bool _isCrashlyticsReady = false; void main() async { // 初始化应用配置 AppConfig.initialize(); // 2. 使用 runZonedGuarded 创建一个隔离区域来捕获所有异步错误 runZonedGuarded( () async { // 1. 确保 Widget 绑定初始化 WidgetsFlutterBinding.ensureInitialized(); // 性能优化:启用手势重采样 GestureBinding.instance.resamplingEnabled = true; // 仅保留首帧前真正必要的初始化 await _prepareAppShell(); _installErrorHandlers(); // 立即运行应用,不等待非必要服务初始化 runApp(const RootAppWithProviders()); WidgetsBinding.instance.addPostFrameCallback((_) { unawaited(_warmUpDeferredServices()); }); }, // 9. runZonedGuarded 的错误回调(这是捕获异步错误的主要方式) (error, stackTrace) { unawaited(_recordFatalError(error, stackTrace)); }, ); } /// 首帧前的必要初始化 Future _prepareAppShell() async { // 配置设备方向:仅竖屏 await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); // Android平台状态栏样式设置 if (Platform.isAndroid) { SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.dark, ), ); } // 键盘工具初始化 SCKeybordUtil.init(); // 使用重试机制初始化存储 await _initStore(); } void _installErrorHandlers() { FlutterError.onError = (details) { FlutterError.presentError(details); unawaited(_recordFlutterError(details)); }; PlatformDispatcher.instance.onError = (error, stack) { unawaited(_recordFatalError(error, stack)); return true; }; } /// 首帧后的后台预热初始化 Future _warmUpDeferredServices() async { try { if (Firebase.apps.isEmpty) { await Firebase.initializeApp(); } _isCrashlyticsReady = true; await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); if (kDebugMode) { debugPrint('Firebase/Crashlytics 后台初始化完成'); } } catch (e, stackTrace) { debugPrint('Firebase 后台初始化异常: $e\n$stackTrace'); } } Future _recordFlutterError(FlutterErrorDetails details) async { if (!_isCrashlyticsReady) { debugPrint( 'Flutter Error before Crashlytics ready: ${details.exceptionAsString()}', ); return; } try { await FirebaseCrashlytics.instance.recordFlutterFatalError(details); } catch (e, stackTrace) { debugPrint('Crashlytics 记录 Flutter 错误失败: $e\n$stackTrace'); } } Future _recordFatalError(Object error, StackTrace stackTrace) async { if (!_isCrashlyticsReady) { debugPrint('Unhandled error before Crashlytics ready: $error'); debugPrintStack(stackTrace: stackTrace); return; } try { await FirebaseCrashlytics.instance.recordError( error, stackTrace, fatal: true, ); } catch (e, recordStackTrace) { debugPrint('Crashlytics 记录异常失败: $e\n$recordStackTrace'); } } /// 带重试的数据存储初始化(重命名自_initializeStorageWithRetry) Future _initStore() async { const maxAttempts = 3; int attemptCount = 0; bool success = false; while (attemptCount < maxAttempts && !success) { attemptCount++; try { await DataPersistence.initialize(); success = true; if (kDebugMode) { debugPrint('数据存储初始化成功(尝试次数: $attemptCount)'); } } catch (e) { debugPrint('数据存储初始化尝试 $attemptCount 失败: $e'); if (attemptCount >= maxAttempts) { debugPrint('数据存储初始化失败,已达最大重试次数: $maxAttempts'); // 不抛出异常,允许应用继续运行 return; } // 递增延迟:500ms, 1000ms, 1500ms... int delayMs = 500 * attemptCount; await Future.delayed(Duration(milliseconds: delayMs)); } } } /// 带有所有Provider的根组件 class RootAppWithProviders extends StatelessWidget { const RootAppWithProviders({super.key}); @override Widget build(BuildContext context) { return MultiProvider(providers: _buildP(), child: const YumiApplication()); } /// 构建应用Provider列表 - 重新排序以优化性能 List _buildP() { return [ // 核心用户相关Provider - 按需初始化,避免阻塞首屏 ChangeNotifierProvider( lazy: true, create: (context) => SocialChatAuthenticationManager(), ), ChangeNotifierProvider( lazy: true, create: (context) => SocialChatUserProfileManager(), ), // UI与主题相关Provider - 懒加载 ChangeNotifierProvider( lazy: true, create: (context) => ThemeManager(), ), ChangeNotifierProvider( lazy: true, create: (context) => LocalizationManager(), ), // 实时通信Provider - 懒加载 ChangeNotifierProvider( lazy: true, create: (context) => RealTimeCommunicationManager(), ), ChangeNotifierProvider( lazy: true, create: (context) => RealTimeMessagingManager(), ), // 房间与社交功能Provider - 懒加载 ChangeNotifierProvider( lazy: true, create: (context) => SocialChatRoomManager(), ), // 礼物与动画系统Provider - 懒加载 ChangeNotifierProvider( lazy: true, create: (context) => SocialChatGiftSystemManager(), ), ChangeNotifierProvider( lazy: true, create: (context) => GiftAnimationManager(), ), // 支付与商店Provider - 懒加载 ChangeNotifierProvider( lazy: true, create: (context) => AndroidPaymentProcessor(), ), ChangeNotifierProvider( lazy: true, create: (context) => IOSPaymentProcessor(), ), ChangeNotifierProvider( lazy: true, create: (context) => ShopManager(), ), // 通用应用管理Provider - 懒加载 ChangeNotifierProvider( lazy: true, create: (context) => SCAppGeneralManager(), ), ]; } } final GlobalKey navigatorKey = GlobalKey(); final RouteObserver routeObserver = RouteObserver(); class YumiApplication extends StatefulWidget { const YumiApplication({super.key}); @override State createState() => _YumiApplicationState(); } class _YumiApplicationState extends State { late fluro.FluroRouter _router; final SCDeepLinkHandler _deepLinkHandler = SCDeepLinkHandler(); @override void initState() { super.initState(); // 将非首帧必需的初始化统一延后到首帧后 WidgetsBinding.instance.addPostFrameCallback((_) { _initRouter(); SCDeviceIdUtils.initDeviceinfo(); unawaited(_initLink()); }); } @override dispose() { _deepLinkHandler.dispose(); super.dispose(); } Future _initLink() async { // 初始化,并传递一个回调函数用于处理链接 await _deepLinkHandler.initDeepLinks( onLinkReceived: (Uri uri) { // 当收到链接时,无论应用在哪个页面,都可以进行路由 _handleLink(uri); }, ); } void _handleLink(Uri uri) { // 这是处理链接的核心路由逻辑 debugPrint('App 根层收到链接: $uri'); } void _initRouter() { _router = fluro.FluroRouter(); SCRoutes.configureRoutes(_router); SCLkApplication.router = _router; } @override Widget build(BuildContext context) { return _buildUI(); } // 构建下拉刷新配置的页脚部件 Widget Function() _buildFooter() { return () => CustomFooter( builder: (BuildContext context, LoadStatus? mode) { Widget body; if (mode == LoadStatus.idle) { body = Text(SCAppLocalizations.of(context)!.pullToLoadMore); } else if (mode == LoadStatus.loading) { body = CupertinoActivityIndicator(color: Colors.white24); } else if (mode == LoadStatus.failed) { body = Text( SCAppLocalizations.of(context)!.loadingFailedClickToRetry, ); } else if (mode == LoadStatus.canLoading) { body = Text(SCAppLocalizations.of(context)!.releaseToLoadMore); } else { body = Text( "", style: TextStyle(fontSize: 12.sp, color: Color(0xff999999)), ); } return Container( height: kTextTabBarHeight + ScreenUtil().statusBarHeight, child: Center(child: body), ); }, ); } Widget _buildUI() { return Consumer( builder: (context, localeProvider, child) { // 只有在LocaleProvider可用时才设置语言 SCGlobalConfig.lang = localeProvider.locale?.languageCode ?? "en"; return Consumer( builder: (context, themeManager, child) { return ScreenUtilInit( designSize: Size(SCScreen.designWidth, SCScreen.designHeight), splitScreenMode: false, minTextAdapt: true, builder: (context, child) { return AnnotatedRegion( value: SystemUiOverlayStyle.dark, child: RefreshConfiguration( headerBuilder: () => MaterialClassicHeader( color: SocialChatTheme.primaryColor, ), footerBuilder: _buildFooter(), child: MaterialApp( title: 'Yumi', locale: localeProvider.locale, localizationsDelegates: const [ SCAppLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: const [ Locale('en', ''), Locale('zh', ''), Locale('ar', ''), Locale('tr', ''), Locale('bn', ''), ], navigatorKey: navigatorKey, debugShowCheckedModeBanner: false, onGenerateRoute: SCLkApplication.router.generator, theme: themeManager.currentTheme, home: const SplashPage(), builder: FlutterSmartDialog.init( builder: (context, child) { return Stack( fit: StackFit.expand, children: [ child ?? const SizedBox.shrink(), const Positioned.fill( child: VapPlusSvgaPlayer(tag: "room_gift"), ), ], ); }, ), navigatorObservers: [routeObserver], ), ), ); }, ); }, ); }, ); } }