如何实现Flutter桌面应用单实例运行?Mutex方案失效求解决
Flutter桌面应用阻止多实例运行的正确实现方案
原代码使用的package:mutex的Mutex是进程内互斥锁,仅能限制同一进程内的并发操作,无法跨进程生效。不同应用实例属于独立进程,内存完全隔离,所以这个方案根本无法阻止多实例运行。
以下是两种可行的实现方案:
方案一:使用文件锁(无需额外依赖)
利用dart:io的文件独占锁特性,创建一个全局唯一的锁文件,当第二个实例尝试获取锁时会失败,以此判断是否已有实例在运行。注意锁需要持续持有直到应用退出,不能提前释放。
import 'dart:io'; import 'package:flutter/material.dart'; void main() async { // 定义全局唯一的锁文件路径,可根据系统调整 final lockFile = File(Platform.isWindows ? '${Platform.environment['APPDATA']}\\my_app.lock' : '${Platform.environment['HOME']}/.my_app.lock'); FileLock? lock; try { // 尝试获取独占锁,阻塞直到拿到锁或失败 lock = await lockFile.open(mode: FileMode.write).then((file) { return file.lockSync(FileLock.exclusive); }); // 成功获取锁,运行应用 runApp(const MyApp()); } catch (_) { // 获取锁失败,说明已有实例在运行 print('应用已在运行中'); exit(0); } // 应用退出时释放锁(可选,进程结束后系统会自动释放) WidgetsBinding.instance.addObserver(LifecycleObserver(() { lock?.release(); lockFile.deleteSync(); })); } class LifecycleObserver extends WidgetsBindingObserver { final VoidCallback onExit; LifecycleObserver(this.onExit); @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.detached) { onExit(); } } } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold(body: Center(child: Text('单实例应用'))), ); } }
方案二:使用single_instance包(更简洁)
这个包专门用于处理Flutter桌面应用的单实例问题,内部封装了跨平台的互斥逻辑。
- 添加依赖到
pubspec.yaml:
dependencies: single_instance: ^2.0.0
- 实现代码:
import 'package:flutter/material.dart'; import 'package:single_instance/single_instance.dart'; import 'dart:io'; void main() async { // 创建唯一实例标识符,建议用应用的包名 final instanceId = 'com.yourcompany.yourapp'; // 尝试创建单实例 final isFirstInstance = await SingleInstance.create(instanceId); if (isFirstInstance) { runApp(const MyApp()); } else { print('应用已在运行中'); exit(0); } } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold(body: Center(child: Text('单实例应用'))), ); } }
内容的提问来源于stack exchange,提问作者Ahmed Hamed
相关产品推荐
相关产品推荐

