118 lines
3.3 KiB
Dart
118 lines
3.3 KiB
Dart
import 'package:autosos_flutter/app.dart';
|
||
import 'package:autosos_flutter/config/constant.dart';
|
||
import 'package:autosos_flutter/service/background_service.dart';
|
||
import 'package:autosos_flutter/service/location_service.dart';
|
||
import 'package:autosos_flutter/service/push_service.dart';
|
||
import 'package:autosos_flutter/service/update_service.dart';
|
||
import 'package:autosos_flutter/util/sp_util.dart';
|
||
import 'package:autosos_flutter/util/xhttp.dart';
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:sentry_dio/sentry_dio.dart';
|
||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||
|
||
/// 应用入口
|
||
///
|
||
/// 启动顺序:
|
||
/// 1. 屏幕方向 / 状态栏
|
||
/// 2. SP 预加载
|
||
/// 3. Sentry 崩溃监控(包住 runApp)
|
||
/// 4. App 启动后:后台服务 / 定位 / 推送 / 检查更新
|
||
Future<void> main() async {
|
||
WidgetsFlutterBinding.ensureInitialized();
|
||
|
||
// 强制竖屏
|
||
await SystemChrome.setPreferredOrientations(const [
|
||
DeviceOrientation.portraitUp,
|
||
DeviceOrientation.portraitDown,
|
||
]);
|
||
|
||
// 状态栏样式
|
||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||
statusBarColor: Colors.transparent,
|
||
statusBarIconBrightness: Brightness.light,
|
||
));
|
||
|
||
// 预加载 SP
|
||
SPUtil().init();
|
||
|
||
// 恢复登录态
|
||
final savedToken = SPUtil().get('accessToken') as String?;
|
||
if (savedToken != null && savedToken.isNotEmpty) {
|
||
Constant.newVersion =
|
||
(SPUtil().get('appver') as String?) ?? Constant.newVersion;
|
||
}
|
||
|
||
// 启动 Sentry(崩溃监控 + Dio 拦截)
|
||
await SentryFlutter.init(
|
||
(options) {
|
||
options.dsn = const String.fromEnvironment(
|
||
'SENTRY_DSN',
|
||
defaultValue: '',
|
||
);
|
||
options.tracesSampleRate = 0.1;
|
||
options.environment = kDebugMode ? 'debug' : 'release';
|
||
},
|
||
appRunner: () async {
|
||
// 注册 Dio → Sentry 拦截(SentryDioExtension 是 Dio 的扩展)
|
||
XHttp.dio.addSentry();
|
||
|
||
// App 启动后异步执行:
|
||
_postBoot();
|
||
|
||
runApp(
|
||
const ProviderScope(
|
||
child: AutososApp(),
|
||
),
|
||
);
|
||
},
|
||
);
|
||
}
|
||
|
||
/// 启动后异步执行:后台服务 / 定位 / 推送 / 更新
|
||
/// 任何步骤失败都不影响 App 启动
|
||
Future<void> _postBoot() async {
|
||
// 后台保活
|
||
try {
|
||
await BackgroundService.instance.init();
|
||
await BackgroundService.instance.start();
|
||
} catch (e) {
|
||
debugPrint('BG init failed: $e');
|
||
}
|
||
|
||
// 定位
|
||
try {
|
||
await LocationService.instance.init();
|
||
} catch (e) {
|
||
debugPrint('Location init failed: $e');
|
||
}
|
||
|
||
// 个推
|
||
try {
|
||
PushService.instance.init();
|
||
} catch (e) {
|
||
debugPrint('Push init failed: $e');
|
||
}
|
||
|
||
// 延迟 2s 后检查更新(避免影响冷启动)
|
||
Future.delayed(const Duration(seconds: 2), () async {
|
||
try {
|
||
final update = await UpdateService.instance.checkUpdate();
|
||
if (update != null && update.latestVersion.isNotEmpty) {
|
||
debugPrint(
|
||
'Update available: ${update.latestVersion}, force=${update.forceUpdate}',
|
||
);
|
||
// 真正的弹窗由 SettingPage 触发
|
||
Constant.NECUPDATE = update.forceUpdate ? 3 : 2;
|
||
} else {
|
||
Constant.NECUPDATE = 1;
|
||
}
|
||
} catch (e) {
|
||
debugPrint('Update check failed: $e');
|
||
Constant.NECUPDATE = 5;
|
||
}
|
||
});
|
||
}
|