128 lines
3.8 KiB
Dart
128 lines
3.8 KiB
Dart
|
|
import 'package:flutter/material.dart';
|
|||
|
|
import 'dart:async';
|
|||
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
|
|
import 'core/theme/app_theme.dart';
|
|||
|
|
import 'core/routes/app_routes.dart';
|
|||
|
|
import 'core/storage/storage_service.dart' as legacy_storage;
|
|||
|
|
import 'core/services/storage_service.dart';
|
|||
|
|
import 'core/services/navigation_service.dart';
|
|||
|
|
import 'core/network/api_client.dart';
|
|||
|
|
import 'core/providers/providers.dart';
|
|||
|
|
import 'core/providers/app_state_provider.dart';
|
|||
|
|
import 'core/config/environment.dart';
|
|||
|
|
import 'shared/widgets/error_handler.dart';
|
|||
|
|
|
|||
|
|
void main() async {
|
|||
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|||
|
|
|
|||
|
|
FlutterError.onError = (FlutterErrorDetails details) {
|
|||
|
|
debugPrint('FlutterError: ${details.exception}');
|
|||
|
|
};
|
|||
|
|
WidgetsBinding.instance.platformDispatcher.onError = (error, stack) {
|
|||
|
|
debugPrint('ZoneError: $error');
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 使用runZonedGuarded包裹启动流程,捕获所有未处理异常
|
|||
|
|
runZonedGuarded(() async {
|
|||
|
|
// 初始化环境配置
|
|||
|
|
_initializeEnvironment();
|
|||
|
|
|
|||
|
|
// 初始化存储服务(两个都初始化以保持兼容性)
|
|||
|
|
await legacy_storage.StorageService.init();
|
|||
|
|
await StorageService.getInstance();
|
|||
|
|
|
|||
|
|
// 初始化API客户端
|
|||
|
|
await ApiClient.getInstance();
|
|||
|
|
|
|||
|
|
// 创建Provider容器
|
|||
|
|
final container = ProviderContainer(
|
|||
|
|
observers: GlobalProviders.observers,
|
|||
|
|
overrides: GlobalProviders.overrides,
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 预加载Provider
|
|||
|
|
await GlobalProviders.preloadProviders(container);
|
|||
|
|
|
|||
|
|
runApp(
|
|||
|
|
UncontrolledProviderScope(
|
|||
|
|
container: container,
|
|||
|
|
child: const MyApp(),
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}, (error, stack) {
|
|||
|
|
debugPrint('ZoneError: $error');
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 初始化环境配置
|
|||
|
|
void _initializeEnvironment() {
|
|||
|
|
// 从编译时参数获取环境配置
|
|||
|
|
const environment = String.fromEnvironment('ENVIRONMENT', defaultValue: 'development');
|
|||
|
|
EnvironmentConfig.setEnvironmentFromString(environment);
|
|||
|
|
|
|||
|
|
// 检查是否有自定义API地址
|
|||
|
|
const customApiUrl = String.fromEnvironment('API_BASE_URL');
|
|||
|
|
|
|||
|
|
debugPrint('========================================');
|
|||
|
|
debugPrint('Environment: ${EnvironmentConfig.environmentName}');
|
|||
|
|
debugPrint('API Base URL: ${EnvironmentConfig.baseUrl}');
|
|||
|
|
if (customApiUrl.isNotEmpty) {
|
|||
|
|
debugPrint('Custom API URL: $customApiUrl');
|
|||
|
|
}
|
|||
|
|
debugPrint('Debug Mode: ${EnvironmentConfig.debugMode}');
|
|||
|
|
debugPrint('Enable Logging: ${EnvironmentConfig.enableLogging}');
|
|||
|
|
debugPrint('========================================');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class MyApp extends ConsumerStatefulWidget {
|
|||
|
|
const MyApp({super.key});
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
ConsumerState<MyApp> createState() => _MyAppState();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class _MyAppState extends ConsumerState<MyApp> {
|
|||
|
|
@override
|
|||
|
|
void initState() {
|
|||
|
|
super.initState();
|
|||
|
|
// 确保应用启动后立即关闭全局加载状态
|
|||
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|||
|
|
ref.read(appStateProvider.notifier).updateLoading(false);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
Widget build(BuildContext context) {
|
|||
|
|
final appState = ref.watch(appStateProvider);
|
|||
|
|
|
|||
|
|
return GlobalErrorHandler(
|
|||
|
|
child: MaterialApp(
|
|||
|
|
title: 'AI English Learning',
|
|||
|
|
theme: AppTheme.lightTheme,
|
|||
|
|
darkTheme: AppTheme.darkTheme,
|
|||
|
|
themeMode: appState.themeMode,
|
|||
|
|
navigatorKey: NavigationService.instance.navigatorKey,
|
|||
|
|
initialRoute: Routes.home,
|
|||
|
|
onGenerateRoute: AppRoutes.onGenerateRoute,
|
|||
|
|
builder: (context, child) {
|
|||
|
|
return Stack(
|
|||
|
|
children: [
|
|||
|
|
child ?? const SizedBox.shrink(),
|
|||
|
|
if (appState.isGlobalLoading)
|
|||
|
|
const Positioned.fill(
|
|||
|
|
child: Material(
|
|||
|
|
color: Colors.black54,
|
|||
|
|
child: Center(
|
|||
|
|
child: CircularProgressIndicator(),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
);
|
|||
|
|
},
|
|||
|
|
),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|