This commit is contained in:
petrovyuri
2025-01-21 14:24:31 +03:00
parent e7b2c31e86
commit 17d096baac
96 changed files with 3575 additions and 0 deletions

107
lib/runner/app_runner.dart Normal file
View File

@@ -0,0 +1,107 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:friflex_starter/app/app.dart';
import 'package:friflex_starter/app/app_env.dart';
import 'package:friflex_starter/di/di_container.dart';
import 'package:friflex_starter/features/debug/app_debug_service.dart';
import 'package:friflex_starter/features/debug/i_debug_service.dart';
import 'package:friflex_starter/features/error/error_screen.dart';
import 'package:friflex_starter/router/app_router.dart';
import 'package:friflex_starter/runner/timer_runner.dart';
import 'package:go_router/go_router.dart';
part 'errors_handlers.dart';
/// Класс, реализующий раннер для конфигурирования приложения при запуске
///
/// Порядок инициализации:
/// 1. _initApp - инициализация конфигурации приложения
/// 2. инициализация репозиториев приложения (будет позже)
/// 3. runApp - запуск приложения
/// 4. _onAppLoaded - после запуска приложения
class AppRunner {
/// Создает экземпляр раннера приложения
///
/// Принимает:
/// - [env] - тип окружения сборки приложения
AppRunner(this.env);
/// Тип окружения сборки приложения¬
final AppEnv env;
/// Контейнер зависимостей приложения
late final IDebugService _debugService;
/// Роутер приложения
late final GoRouter router;
/// Таймер для отслеживания времени инициализации приложения
late final TimerRunner _timerRunner;
/// Метод для запуска приложения
Future<void> run() async {
WidgetsFlutterBinding.ensureInitialized();
// Инициализация сервиса отладки
_debugService = AppDebugService();
_timerRunner = TimerRunner(_debugService);
// Инициализация приложения
await _initApp();
// Инициализация метода обработки ошибок
_initErrorHandlers(_debugService);
// Инициализация репозиториев и сервисов
final diContainer = await _initDependencies(_debugService);
// Инициализация роутера
router = AppRouter.createRouter(_debugService);
runApp(
App(diContainer: diContainer, router: router),
);
await _onAppLoaded();
}
/// Метод инициализации приложения,
/// выполняется до запуска приложения
Future<void> _initApp() async {
// Запрет на поворот экрана
await SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp],
);
// Заморозка первого кадра (сплеш)
WidgetsBinding.instance.deferFirstFrame();
}
/// Метод срабатывает после запуска приложения
Future<void> _onAppLoaded() async {
// Разморозка первого кадра (сплеш)
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.allowFirstFrame();
});
_timerRunner.stop();
}
/// Метод для инициализации зависимостей приложения
Future<DiContainer> _initDependencies(IDebugService debugService) async {
debugService.log('Тип сборки: ${env.name}');
final diContainer = DiContainer(
env: env,
dService: debugService,
);
await diContainer.init(
onProgress: _timerRunner.logOnProgress,
onComplete: _timerRunner.logOnComplete,
onError: _timerRunner.logOnError,
);
return diContainer;
}
}

View File

@@ -0,0 +1,27 @@
part of 'app_runner.dart';
/// Метод инициализации обработчиков ошибок
void _initErrorHandlers(IDebugService debugService) {
// Обработка ошибок в приложении
FlutterError.onError = (details) {
_showErrorScreen();
debugService.handleError(details.exception, details.stack,
'FlutterError.onError: ${details.exceptionAsString()}',);
};
// Обработка асинхронных ошибок в приложении
PlatformDispatcher.instance.onError = (error, stack) {
_showErrorScreen();
debugService.handleError(error, stack, 'PlatformDispatcher: $error');
return true;
};
}
/// Метод для показа экрана ошибки
void _showErrorScreen() {
WidgetsBinding.instance.addPostFrameCallback((_) {
AppRouter.rootNavigatorKey.currentState?.push(
MaterialPageRoute(
builder: (_) => const ErrorScreen(),
),
);
});
}

View File

@@ -0,0 +1,49 @@
import 'package:friflex_starter/features/debug/i_debug_service.dart';
/// {@template TimerRunner}
/// Класс для подсчета времени запуска приложения
/// {@endtemplate}
class TimerRunner {
/// {@macro TimerRunner}
TimerRunner(this._debugService) {
_stopwatch.start();
}
/// Сервис для отладки
final IDebugService _debugService;
/// Секундомер для подсчета времени инициализации
final _stopwatch = Stopwatch();
/// Метод для остановки секундомера и вывода времени
/// полной инициализации приложения
void stop() {
_stopwatch.stop();
_debugService.log(
'Время инициализации приложения: ${_stopwatch.elapsedMilliseconds} мс',
);
}
/// Метод для обработки прогресса инициализации зависимостей
void logOnProgress(String name) {
_debugService.log(
'$name успешная инициализация, прогресс: ${_stopwatch.elapsedMilliseconds} мс',
);
}
/// Метод для обработки прогресса инициализации зависимостей
void logOnComplete(String message) {
_debugService.log(
'$message, прогресс: ${_stopwatch.elapsedMilliseconds} мс',
);
}
/// Метод для обработки прогресса инициализации зависимостей
void logOnError(
String message, {
Object? error,
StackTrace? stackTrace,
}) {
_debugService.error(message, error, stackTrace);
}
}