- SMS 화면에서 그림자가 제대로 표시되지 않던 문제 수정 - Stack 구조를 Container로 단순화하여 렌더링 최적화 - RenderFlex overflow 오류 해결 (패딩 및 아이콘 크기 조정) - Android 패키지명 변경 및 빌드 설정 업데이트
169 lines
6.0 KiB
Dart
169 lines
6.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
|
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
import 'models/subscription_model.dart';
|
|
import 'models/category_model.dart';
|
|
import 'providers/subscription_provider.dart';
|
|
import 'providers/app_lock_provider.dart';
|
|
import 'providers/notification_provider.dart';
|
|
import 'providers/navigation_provider.dart';
|
|
import 'services/notification_service.dart';
|
|
import 'providers/category_provider.dart';
|
|
import 'providers/locale_provider.dart';
|
|
import 'providers/theme_provider.dart';
|
|
import 'l10n/app_localizations.dart';
|
|
import 'theme/adaptive_theme.dart';
|
|
import 'routes/app_routes.dart';
|
|
import 'navigation/app_navigation_observer.dart';
|
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
|
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
|
import 'dart:io' show Platform;
|
|
import 'dart:async' show unawaited;
|
|
import 'utils/memory_manager.dart';
|
|
import 'utils/performance_optimizer.dart';
|
|
import 'navigator_key.dart';
|
|
|
|
// AdMob 활성화 플래그 (개발 중 false, 프로덕션 시 true로 변경)
|
|
const bool enableAdMob = false;
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
// 구글 모바일 광고 SDK 초기화 (웹이 아니고, Android/iOS에서만)
|
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS) && enableAdMob) {
|
|
unawaited(MobileAds.instance.initialize());
|
|
}
|
|
|
|
// 성능 최적화 설정
|
|
MemoryManager.optimizeImageCache();
|
|
MemoryManager().startAutoCleanup();
|
|
|
|
// 앱 시작 시 이미지 캐시 관리
|
|
try {
|
|
// 메모리 이미지 캐시는 유지하지만 필요한 경우 삭제할 수 있도록 준비
|
|
|
|
// 오래된 디스크 캐시 파일만 지우기 (새로운 것은 유지)
|
|
await DefaultCacheManager().emptyCache();
|
|
|
|
if (kDebugMode) {
|
|
print('이미지 캐시 관리 초기화 완료');
|
|
PerformanceOptimizer.checkConstOptimization();
|
|
}
|
|
} catch (e) {
|
|
if (kDebugMode) {
|
|
print('캐시 초기화 오류: $e');
|
|
}
|
|
}
|
|
|
|
// Hive 초기화
|
|
await Hive.initFlutter();
|
|
Hive.registerAdapter(SubscriptionModelAdapter());
|
|
Hive.registerAdapter(CategoryModelAdapter());
|
|
await Hive.openBox<SubscriptionModel>('subscriptions');
|
|
await Hive.openBox<CategoryModel>('categories');
|
|
final appLockBox = await Hive.openBox<bool>('app_lock');
|
|
// 알림 서비스를 가장 먼저 초기화
|
|
await NotificationService.init();
|
|
|
|
final subscriptionProvider = SubscriptionProvider();
|
|
final categoryProvider = CategoryProvider();
|
|
final localeProvider = LocaleProvider();
|
|
final notificationProvider = NotificationProvider();
|
|
final themeProvider = ThemeProvider();
|
|
final navigationProvider = NavigationProvider();
|
|
|
|
await subscriptionProvider.init();
|
|
await categoryProvider.init();
|
|
await localeProvider.init();
|
|
await notificationProvider.init();
|
|
await themeProvider.initialize();
|
|
|
|
// NotificationProvider에 SubscriptionProvider 연결 (알림 재예약용)
|
|
// SRP 원칙에 따라 다른 Provider 객체를 명시적으로 주입
|
|
notificationProvider.setSubscriptionProvider(subscriptionProvider);
|
|
|
|
// 별도의 비동기 함수로 알림 관련 초기화 오류 처리
|
|
Future.delayed(Duration.zero, () {
|
|
try {
|
|
if (notificationProvider.isPaymentEnabled) {
|
|
// 백그라운드에서 비동기적으로 알림 설정 업데이트
|
|
NotificationService.reschedulAllNotifications(
|
|
subscriptionProvider.subscriptions);
|
|
}
|
|
} catch (e) {
|
|
debugPrint('알림 초기 설정 중 오류 발생: $e');
|
|
}
|
|
});
|
|
|
|
runApp(
|
|
MultiProvider(
|
|
providers: [
|
|
ChangeNotifierProvider(create: (_) => subscriptionProvider),
|
|
ChangeNotifierProvider(create: (_) => categoryProvider),
|
|
ChangeNotifierProvider(create: (_) => AppLockProvider(appLockBox)),
|
|
ChangeNotifierProvider(create: (_) => notificationProvider),
|
|
ChangeNotifierProvider(create: (_) => localeProvider),
|
|
ChangeNotifierProvider(create: (_) => themeProvider),
|
|
ChangeNotifierProvider(create: (_) => navigationProvider),
|
|
],
|
|
child: const SubManagerApp(),
|
|
),
|
|
);
|
|
}
|
|
|
|
class SubManagerApp extends StatelessWidget {
|
|
const SubManagerApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Consumer2<LocaleProvider, ThemeProvider>(
|
|
builder: (context, localeProvider, themeProvider, child) {
|
|
// 시스템 UI 오버레이 스타일 적용
|
|
AdaptiveTheme.applySystemUIOverlay(context);
|
|
|
|
return MaterialApp(
|
|
key: ValueKey(localeProvider.locale),
|
|
title: 'Digital Rent Manager',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: themeProvider.getTheme(context),
|
|
locale: localeProvider.locale,
|
|
localizationsDelegates: const [
|
|
AppLocalizationsDelegate(),
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
],
|
|
supportedLocales: const [
|
|
Locale('en'),
|
|
Locale('ko'),
|
|
Locale('ja'),
|
|
Locale('zh'),
|
|
],
|
|
navigatorKey: navigatorKey,
|
|
navigatorObservers: [AppNavigationObserver()],
|
|
initialRoute: AppRoutes.splash,
|
|
routes: AppRoutes.getRoutes(),
|
|
onGenerateRoute: AppRoutes.generateRoute,
|
|
builder: (context, child) {
|
|
// 성능 최적화 및 메모리 관리
|
|
if (kDebugMode) {
|
|
PerformanceOptimizer().startFrameMonitoring();
|
|
}
|
|
|
|
return MediaQuery(
|
|
data: MediaQuery.of(context).copyWith(
|
|
textScaler:
|
|
TextScaler.linear(themeProvider.largeText ? 1.2 : 1.0),
|
|
disableAnimations: themeProvider.reduceMotion,
|
|
),
|
|
child: child!,
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|