11import 'dart:io' ;
2- import 'dart:ffi' ;
32import 'dart:developer' ;
43import 'package:get/get.dart' ;
5- import 'package:win32/win32.dart' ;
64import 'package:pure_live/common/index.dart' ;
75import 'package:pure_live/plugins/global.dart' ;
86import 'package:hive_ce_flutter/hive_flutter.dart' ;
97import 'package:launch_at_startup/launch_at_startup.dart' ;
10- import 'package:package_info_plus/package_info_plus .dart' ;
8+ import 'package:pure_live/common/global/windows_utils .dart' ;
119import 'package:pure_live/common/utils/hive_pref_util.dart' ;
1210import 'package:pure_live/common/global/platform_utils.dart' ;
1311import 'package:pure_live/modules/live_play/player_state.dart' ;
14- import 'package:flutter_single_instance/flutter_single_instance.dart' ;
1512import 'package:pure_live/common/global/platform/mobile_manager.dart' ;
1613import 'package:pure_live/common/global/platform/desktop_manager.dart' ;
1714import 'package:pure_live/common/services/bilibili_account_service.dart' ;
15+ import 'package:package_info_plus/package_info_plus.dart' show PackageInfo;
1816
1917class AppInitializer {
20- // 单例实例
2118 static final AppInitializer _instance = AppInitializer ._internal ();
22-
23- // 是否已经初始化
2419 bool _isInitialized = false ;
2520
26- // 工厂构造函数,返回单例
27- factory AppInitializer () {
28- return _instance;
29- }
30-
31- // 私有构造函数
21+ factory AppInitializer () => _instance;
3222 AppInitializer ._internal ();
3323
34- // 初始化方法
3524 Future <void > initialize (List <String > args) async {
3625 if (_isInitialized) return ;
37-
3826 WidgetsFlutterBinding .ensureInitialized ();
3927
40- // 👇 从启动参数获取实例 ID
4128 String instanceId = getInstanceIdFromArgs (args);
4229
43- // 👇 每个实例使用独立 Hive 路径
44- final appDir = await getApplicationDocumentsDirectory ();
45- String path = '${appDir .path }${Platform .pathSeparator }pure_live${Platform .pathSeparator }$instanceId ' ;
46- if (instanceId.isEmpty) {
47- path = '${appDir .path }${Platform .pathSeparator }pure_live' ;
48- }
4930 if (PlatformUtils .isDesktopNotMac) {
50- final lockFile = File ('$path ${Platform .pathSeparator }app_instance.lock' );
51-
52- try {
53- if (! lockFile.parent.existsSync ()) lockFile.parent.createSync (recursive: true );
54- final raf = lockFile.openSync (mode: FileMode .write);
55- raf.lockSync ();
56- } catch (e) {
57- log ("检测到实例 [$instanceId ] 文件夹已被锁定,正在唤醒已有窗口..." );
58- final hwnd = FindWindow (nullptr, TEXT ('纯粹直播' ));
59- if (hwnd != 0 ) {
60- if (IsIconic (hwnd) != 0 ) ShowWindow (hwnd, SW_RESTORE );
61- SetForegroundWindow (hwnd);
62- }
31+ if (WindowUtils .wakeUpByProp (instanceId)) {
32+ log ("Instance [$instanceId ] already running. Waking up and exiting." );
6333 exit (0 );
6434 }
6535 }
36+
6637 if (PlatformUtils .isDesktop) {
6738 await DesktopManager .initialize ();
6839 } else if (PlatformUtils .isMobile) {
6940 await MobileManager .initialize ();
7041 }
7142
43+ final appDir = await getApplicationDocumentsDirectory ();
44+ String path =
45+ '${appDir .path }${Platform .pathSeparator }pure_live${instanceId .isNotEmpty ? "${Platform .pathSeparator }$instanceId " : "" }' ;
46+
7247 PrefUtil .prefs = await SharedPreferences .getInstance ();
48+ initService ();
49+
7350 try {
7451 await Hive .initFlutter (path);
7552 await HivePrefUtil .init ();
7653 } catch (e) {
77- log (e.toString (), name: 'Hive' );
78- exit (0 );
54+ log ("Hive Init Error: $e " );
7955 }
56+
8057 MediaKit .ensureInitialized ();
8158 await SupaBaseManager .getInstance ().initial ();
8259
8360 if (PlatformUtils .isDesktop) {
8461 await DesktopManager .postInitialize ();
62+ Future .delayed (const Duration (milliseconds: 800 ), () {
63+ WindowUtils .markCurrentWindow (instanceId);
64+ });
65+ }
66+ if (PlatformUtils .isDesktopNotMac) {
67+ // 只有主实例(instanceId 为空)才注册自启,避免多个实例互相覆盖注册表
68+ if (instanceId.isEmpty) {
69+ await _setupLaunchAtStartup ();
70+ }
8571 }
8672
8773 initRefresh ();
88- initService ();
74+ _isInitialized = true ;
75+ }
8976
90- if (PlatformUtils .isDesktopNotMac) {
91- if (! await FlutterSingleInstance ().isFirstInstance ()) {
92- log ("Default instance is already running" );
93- exit (0 );
77+ String getInstanceIdFromArgs (List <String > args) {
78+ for (var arg in args) {
79+ if (arg.startsWith ('--instance=' )) {
80+ var parts = arg.split ('=' );
81+ return parts.length > 1 ? parts[1 ] : '' ;
9482 }
95- await _setupLaunchAtStartup ();
9683 }
97- _isInitialized = true ;
84+ return '' ;
9885 }
9986
100- // 提取 launchAtStartup 设置
101- Future <void > _setupLaunchAtStartup () async {
87+ Future <void > _setupLaunchAtStartup () async {
10288 PackageInfo packageInfo = await PackageInfo .fromPlatform ();
10389 launchAtStartup.setup (
10490 appName: packageInfo.appName,
@@ -114,17 +100,6 @@ class AppInitializer {
114100 }
115101 }
116102
117- // 工具方法:解析 instanceId
118- String getInstanceIdFromArgs (List <String > args) {
119- for (var arg in args) {
120- if (arg.startsWith ('--instance=' )) {
121- return arg.split ('=' )[1 ];
122- }
123- return '' ;
124- }
125- return '' ;
126- }
127-
128103 void initService () {
129104 Get .put (SettingsService ());
130105 Get .put (AuthController ());
@@ -135,6 +110,5 @@ class AppInitializer {
135110 Get .put (GlobalPlayerState ());
136111 }
137112
138- // 检查是否已初始化
139113 bool get isInitialized => _isInitialized;
140114}
0 commit comments