389 lines
14 KiB
Dart
389 lines
14 KiB
Dart
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:aslan/chatvibe_core/utilities/at_keybord_util.dart';
|
||
import 'package:aslan/chatvibe_data/sources/local/at_foreground_service_helper.dart';
|
||
import 'package:aslan/chatvibe_data/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 'chatvibe_core/config/app_config.dart';
|
||
import 'chatvibe_core/constants/at_global_config.dart';
|
||
import 'chatvibe_core/constants/at_screen.dart';
|
||
import 'chatvibe_core/routes/at_routes.dart';
|
||
import 'chatvibe_core/routes/at_lk_application.dart';
|
||
import 'chatvibe_core/utilities/at_deep_link_handler.dart';
|
||
import 'chatvibe_core/utilities/at_deviceId_utils.dart';
|
||
import 'chatvibe_features/splash/splash_page.dart';
|
||
import 'chatvibe_managers/app_general_manager.dart';
|
||
import 'chatvibe_managers/apple_payment_manager.dart';
|
||
import 'chatvibe_managers/audio_manager.dart';
|
||
import 'chatvibe_managers/authentication_manager.dart';
|
||
import 'chatvibe_managers/dynamic_content_manager.dart';
|
||
import 'chatvibe_managers/gift_animation_manager.dart';
|
||
import 'chatvibe_managers/gift_system_manager.dart';
|
||
import 'chatvibe_managers/google_payment_manager.dart';
|
||
import 'chatvibe_managers/localization_manager.dart';
|
||
import 'chatvibe_managers/room_manager.dart';
|
||
import 'chatvibe_managers/rtc_manager.dart';
|
||
import 'chatvibe_managers/rtm_manager.dart';
|
||
import 'chatvibe_managers/shop_manager.dart';
|
||
import 'chatvibe_managers/theme_manager.dart';
|
||
import 'chatvibe_managers/user_profile_manager.dart';
|
||
import 'chatvibe_ui/theme/chatvibe_theme.dart';
|
||
|
||
|
||
void main() async {
|
||
|
||
// 初始化应用配置
|
||
AppConfig.initialize();
|
||
|
||
|
||
// 2. 使用 runZonedGuarded 创建一个隔离区域来捕获所有异步错误
|
||
runZonedGuarded(
|
||
() async {
|
||
// 1. 确保 Widget 绑定初始化
|
||
WidgetsFlutterBinding.ensureInitialized();
|
||
// 性能优化:启用手势重采样
|
||
GestureBinding.instance.resamplingEnabled = true;
|
||
// 阶段1:初始化绝对必要的服务(不阻塞UI)
|
||
await _initializeEssentialServices();
|
||
// 使用重试机制初始化存储
|
||
await _initializeStorageWithRetry();
|
||
// 立即运行应用,不等待非必要服务初始化
|
||
runApp(const MyAppWithProviders());
|
||
|
||
// 阶段2:在应用启动后初始化非必要服务
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
_initializeNonEssentialServices();
|
||
});
|
||
},
|
||
// 9. runZonedGuarded 的错误回调(这是捕获异步错误的主要方式)
|
||
(error, stackTrace) {
|
||
// 这是捕获 runZonedGuarded 区域内所有未捕获异步错误的地方
|
||
FirebaseCrashlytics.instance.recordError(error, stackTrace, fatal: true);
|
||
debugPrint('Zoned Error: $error\nStack: $stackTrace');
|
||
},
|
||
);
|
||
}
|
||
|
||
/// 初始化绝对必要的服务
|
||
Future<void> _initializeEssentialServices() async {
|
||
// 设置屏幕方向
|
||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||
|
||
// 设置状态栏样式
|
||
if (Platform.isAndroid) {
|
||
SystemChrome.setSystemUIOverlayStyle(
|
||
const SystemUiOverlayStyle(
|
||
statusBarColor: Colors.transparent,
|
||
statusBarIconBrightness: Brightness.dark,
|
||
),
|
||
);
|
||
}
|
||
|
||
// 初始化键盘监听
|
||
ATKeybordUtil.initOperation();
|
||
|
||
// 初始化 Firebase(必需)
|
||
try {
|
||
await Firebase.initializeApp();
|
||
debugPrint('Firebase initialized successfully');
|
||
} catch (e, stackTrace) {
|
||
debugPrint('Firebase initialization failed: $e\n$stackTrace');
|
||
// 即使 Firebase 初始化失败,也继续运行应用
|
||
// 记录错误到控制台,但不崩溃
|
||
}
|
||
|
||
// 设置错误处理
|
||
FlutterError.onError = (details) {
|
||
FirebaseCrashlytics.instance.recordFlutterFatalError(details);
|
||
FlutterError.presentError(details);
|
||
};
|
||
|
||
// 设置顶级的异步错误处理器
|
||
PlatformDispatcher.instance.onError = (error, stack) {
|
||
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
|
||
return true;
|
||
};
|
||
|
||
// 启用 Crashlytics
|
||
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
|
||
}
|
||
|
||
/// 初始化非必要服务(延迟执行)
|
||
Future<void> _initializeNonEssentialServices() async {
|
||
try {
|
||
// 初始化其他非必要服务
|
||
ATForegroundServiceHelper().initialize();
|
||
|
||
debugPrint('Non-essential services initialized successfully');
|
||
} catch (e) {
|
||
debugPrint('Non-essential services initialization failed: $e');
|
||
// 不阻塞应用,记录错误即可
|
||
}
|
||
}
|
||
|
||
/// 带重试机制的存储初始化
|
||
Future<void> _initializeStorageWithRetry() async {
|
||
const maxRetries = 3;
|
||
|
||
for (int i = 0; i < maxRetries; i++) {
|
||
try {
|
||
await DataPersistence.initialize();
|
||
return; // 成功则退出
|
||
} catch (e) {
|
||
debugPrint('DataPersistence initialization attempt ${i + 1} failed: $e');
|
||
|
||
if (i == maxRetries - 1) {
|
||
// 最后一次尝试也失败,记录错误但不崩溃
|
||
debugPrint('DataPersistence initialization failed after $maxRetries attempts: $e');
|
||
return; // 不重新抛出异常,继续运行
|
||
}
|
||
|
||
// 等待一段时间后重试
|
||
await Future.delayed(Duration(milliseconds: 500 * (i + 1)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 带有所有Provider的根组件
|
||
class MyAppWithProviders extends StatelessWidget {
|
||
const MyAppWithProviders({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return MultiProvider(providers: _buildProviders(), child: const MyApp());
|
||
}
|
||
|
||
/// 创建Provider列表 - 优化为懒加载
|
||
List<SingleChildWidget> _buildProviders() {
|
||
return [
|
||
// 认证相关Provider - 保持非懒加载
|
||
ChangeNotifierProvider<ChatVibeAuthenticationManager>(
|
||
lazy: false,
|
||
create: (context) => ChatVibeAuthenticationManager(),
|
||
),
|
||
ChangeNotifierProvider<ChatVibeUserProfileManager>(
|
||
lazy: false,
|
||
create: (context) => ChatVibeUserProfileManager(),
|
||
),
|
||
|
||
// 其他Provider改为懒加载,使用时才初始化
|
||
ChangeNotifierProvider<AppGeneralManager>(
|
||
lazy: true,
|
||
create: (context) => AppGeneralManager(),
|
||
),
|
||
ChangeNotifierProvider<ChatVibeRoomManager>(
|
||
lazy: true,
|
||
create: (context) => ChatVibeRoomManager(),
|
||
),
|
||
ChangeNotifierProvider<RtcProvider>(
|
||
lazy: true,
|
||
create: (context) => RealTimeCommunicationManager(),
|
||
),
|
||
ChangeNotifierProvider<RtmProvider>(
|
||
lazy: true,
|
||
create: (context) => RealTimeMessagingManager(),
|
||
),
|
||
ChangeNotifierProvider<GiftProvider>(
|
||
lazy: true,
|
||
create: (context) => ChatVibeGiftSystemManager(),
|
||
),
|
||
ChangeNotifierProvider<GiftAnimationManager>(
|
||
lazy: true,
|
||
create: (context) => GiftAnimationManager(),
|
||
),
|
||
ChangeNotifierProvider<LocalizationManager>(
|
||
lazy: true,
|
||
create: (context) => LocalizationManager(),
|
||
),
|
||
ChangeNotifierProvider<ThemeManager>(
|
||
lazy: true,
|
||
create: (context) => ThemeManager(),
|
||
),
|
||
ChangeNotifierProvider<GooglePaymentManager>(
|
||
lazy: true,
|
||
create: (context) => GooglePaymentManager(),
|
||
),
|
||
ChangeNotifierProvider<ApplePaymentManager>(
|
||
lazy: true,
|
||
create: (context) => ApplePaymentManager(),
|
||
),
|
||
ChangeNotifierProvider<ShopManager>(
|
||
lazy: true,
|
||
create: (context) => ShopManager(),
|
||
),
|
||
ChangeNotifierProvider<AudioManager>(
|
||
lazy: true,
|
||
create: (context) => AudioManager(),
|
||
),
|
||
ChangeNotifierProvider<ChatVibeDynamicContentManager>(
|
||
lazy: true,
|
||
create: (context) => ChatVibeDynamicContentManager(),
|
||
),
|
||
];
|
||
}
|
||
}
|
||
|
||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
||
|
||
class MyApp extends StatefulWidget {
|
||
const MyApp({super.key});
|
||
|
||
@override
|
||
State<MyApp> createState() => _MyAppState();
|
||
}
|
||
|
||
class _MyAppState extends State<MyApp> {
|
||
late fluro.FluroRouter _router;
|
||
final ATDeepLinkHandler _deepLinkHandler = ATDeepLinkHandler();
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
// 延迟初始化路由
|
||
_initializeRouter();
|
||
_initDeepLinking();
|
||
// 延迟初始化设备信息
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
ATDeviceIdUtils.initDeviceinfo();
|
||
});
|
||
}
|
||
|
||
@override
|
||
dispose() {
|
||
_deepLinkHandler.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
Future<void> _initDeepLinking() async {
|
||
// 初始化,并传递一个回调函数用于处理链接
|
||
await _deepLinkHandler.initDeepLinks(
|
||
onLinkReceived: (Uri uri) {
|
||
// 当收到链接时,无论应用在哪个页面,都可以进行路由
|
||
_handleDeepLink(uri);
|
||
},
|
||
);
|
||
}
|
||
|
||
void _handleDeepLink(Uri uri) {
|
||
// 这是处理链接的核心路由逻辑
|
||
print('App 根层收到链接: $uri');
|
||
String path = uri.path;
|
||
String id = uri.queryParameters['id'] ?? '';
|
||
}
|
||
|
||
void _initializeRouter() {
|
||
_router = fluro.FluroRouter();
|
||
ATRoutes.configureRoutes(_router);
|
||
ATLkApplication.router = _router;
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return _buildAppContent();
|
||
}
|
||
|
||
Widget _buildAppContent() {
|
||
return Consumer<LocalizationManager>(
|
||
builder: (context, localeProvider, child) {
|
||
// 只有在LocaleProvider可用时才设置语言
|
||
ATGlobalConfig.lang = localeProvider.locale?.languageCode ?? "en";
|
||
return Consumer<ThemeManager>(
|
||
builder: (context, themeManager, child) {
|
||
return ScreenUtilInit(
|
||
designSize: Size(ATScreen.designWidth, ATScreen.designHeight),
|
||
splitScreenMode: false,
|
||
minTextAdapt: true,
|
||
builder: (context, child) {
|
||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||
value: SystemUiOverlayStyle.dark,
|
||
child: RefreshConfiguration(
|
||
headerBuilder: () => MaterialClassicHeader(color: ChatVibeTheme.primaryColor),
|
||
footerBuilder:
|
||
() => CustomFooter(
|
||
builder: (BuildContext context, LoadStatus? mode) {
|
||
Widget body;
|
||
if (mode == LoadStatus.idle) {
|
||
body = Text(
|
||
ATAppLocalizations.of(context)!.pullToLoadMore,
|
||
);
|
||
} else if (mode == LoadStatus.loading) {
|
||
body = CupertinoActivityIndicator();
|
||
} else if (mode == LoadStatus.failed) {
|
||
body = Text(
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.loadingFailedClickToRetry,
|
||
);
|
||
} else if (mode == LoadStatus.canLoading) {
|
||
body = Text(
|
||
ATAppLocalizations.of(context)!.releaseToLoadMore,
|
||
);
|
||
} else {
|
||
body = Text(
|
||
"",
|
||
style: TextStyle(
|
||
fontSize: 12.sp,
|
||
color: Color(0xff999999),
|
||
),
|
||
);
|
||
}
|
||
return Container(
|
||
height:
|
||
kTextTabBarHeight + ScreenUtil().statusBarHeight,
|
||
child: Center(child: body),
|
||
);
|
||
},
|
||
),
|
||
child: MaterialApp(
|
||
title: 'Aslan',
|
||
locale: Provider.of<LocalizationManager>(context).locale,
|
||
localizationsDelegates: [
|
||
ATAppLocalizations.delegate,
|
||
GlobalMaterialLocalizations.delegate,
|
||
GlobalCupertinoLocalizations.delegate,
|
||
GlobalWidgetsLocalizations.delegate,
|
||
],
|
||
supportedLocales: [
|
||
const Locale('en', ''),
|
||
const Locale('zh', ''),
|
||
const Locale('ar', ''),
|
||
const Locale('tr', ''),
|
||
const Locale('bn', ''),
|
||
],
|
||
navigatorKey: navigatorKey,
|
||
debugShowCheckedModeBanner: false,
|
||
onGenerateRoute: ATLkApplication.router.generator,
|
||
theme: themeManager.currentTheme,
|
||
home: SplashPage(),
|
||
builder: FlutterSmartDialog.init(),
|
||
navigatorObservers: [routeObserver],
|
||
),
|
||
),
|
||
);
|
||
},
|
||
);
|
||
},
|
||
);
|
||
},
|
||
);
|
||
}
|
||
}
|