Flutter单实例控制插件unix_single_instance的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter单实例控制插件unix_single_instance的使用

限制一个Linux或Mac OS X应用在同一时间只能打开一个实例(目前为每个用户)。

这通过使用Unix套接字来确保只有一个实例。虽然还有其他方法可以实现这一点,但这种方法是最“可移植”的。对于Windows支持,可以考虑添加:windows_single_instance插件。

安装

  1. 在你的应用程序的main函数中添加async修饰符。
  2. 编写一个函数cmdProcessor(List<dynamic> decodedArgs),用于重新处理命令行选项。
  3. 在适当的情况下调用unixSingleInstance()。在主函数中的放置位置根据个人喜好决定。

注意事项

如果使用flutter,建议与window_manager插件一起使用。

未来扩展

目前它是在每个用户的基础上,并且忽略了多个显示器的情况。可以通过选项来切换是否是基于X、基于用户的等(如果基于X和基于用户且仅限于Linux,可以考虑使用dbus – 不是强烈推荐)。

示例

import 'package:flutter/material.dart';
import 'package:unix_single_instance/unix_single_instance.dart';
import 'package:window_manager/window_manager.dart';

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 检查当前操作系统是否为Linux
  if (Platform.isLinux) {
    // 如果无法创建Unix套接字实例,则退出程序
    if (!await unixSingleInstance(args, cmdProcessor)) {
      exit(0);
      return;
    }
  } 
  // 检查当前操作系统是否为MacOS
  else if (Platform.isMacOS) {
    // 如果无法创建Unix套接字实例,则退出程序
    if (!await unixSingleInstance(args, cmdProcessor)) {
      exit(0);
      return;
    }
  }

  // 启动应用程序
  runApp(const MyApp());
}

// 处理命令行参数
void cmdProcessor(List<dynamic> decodedArgs) {
  if (decodedArgs.isEmpty && !Platform.isWindows) {
    // 等待窗口管理器准备显示
    windowManager.waitUntilReadyToShow(null, () async {
      await windowManager.show();
      await windowManager.focus();
    });
  }
  // 遍历所有解码后的参数
  for (var each in decodedArgs) {
    if (each is! String) {
      continue;
    }
    // 对字符串参数执行某些操作
    doSomethingWithThis(each);
  }
}

更多关于Flutter单实例控制插件unix_single_instance的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter单实例控制插件unix_single_instance的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter应用中,使用unix_single_instance插件可以帮助你实现单实例控制,确保应用程序在同一时间只能运行一个实例。如果尝试启动第二个实例,你可以配置该插件以发送消息到已经运行的实例,或者执行其他操作。

以下是如何在Flutter项目中使用unix_single_instance插件的示例代码:

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加unix_single_instance依赖:

dependencies:
  flutter:
    sdk: flutter
  unix_single_instance: ^0.x.x  # 请检查最新版本号并替换

然后运行flutter pub get来安装依赖。

2. 使用插件

在你的Flutter应用的主入口文件(通常是main.dart)中,配置并使用unix_single_instance插件。

import 'package:flutter/material.dart';
import 'package:unix_single_instance/unix_single_instance.dart';

void main() async {
  // 初始化UnixSingleInstance插件
  final unixSingleInstance = UnixSingleInstance();

  // 检查是否是单实例
  bool isFirstInstance = await unixSingleInstance.isFirstInstance;

  if (isFirstInstance) {
    // 如果是第一个实例,运行主应用
    runApp(MyApp());
  } else {
    // 如果不是第一个实例,可以处理消息或执行其他操作
    // 例如,发送一个通知到已经运行的实例
    print('另一个实例已经在运行');

    // 你也可以监听来自其他实例的消息
    unixSingleInstance.messageStream.listen((message) {
      print('收到来自其他实例的消息: $message');
      // 在这里处理消息,例如显示一个通知
    });

    // 退出当前实例
    exit(0);
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter 单实例控制示例'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 启动第二个实例的示例代码(仅用于测试)
              // 注意:在实际应用中,用户通常不会这样启动第二个实例
              // 这里只是为了演示如何接收消息
              Process.start(Platform.resolvedExecutable, [Platform.script.toFilePath()]);
            },
            child: Text('启动另一个实例(测试用)'),
          ),
        ),
      ),
    );
  }
}

3. 处理消息(可选)

如果你希望在已经运行的实例中处理来自新实例的消息,你可以使用sendMessageToFirstInstance方法。例如,在按钮点击事件中:

ElevatedButton(
  onPressed: () async {
    // 发送消息到第一个实例
    await unixSingleInstance.sendMessageToFirstInstance('Hello from the new instance!');
    // 退出当前实例
    exit(0);
  },
  child: Text('发送消息到第一个实例并退出'),
),

确保在第一个实例中正确监听消息流,如上所示。

注意事项

  • unix_single_instance插件主要适用于Unix-like系统(如Linux和macOS)。在Windows上,你可能需要使用其他方法或插件来实现单实例控制。
  • 在实际应用中,用户通常不会通过代码手动启动第二个实例。这个示例主要用于演示如何接收和处理来自新实例的消息。

通过上述代码,你可以在Flutter应用中实现单实例控制,并确保同一时间只有一个实例在运行。

回到顶部