如何在Flutter应用中检测macOS darkwake状态并阻止同步任务?
问题描述
我用Dart/Flutter的Timer.periodic配置了服务器同步任务,发现macOS Sequoia在休眠时会偶尔进入darkwake模式,此时同步任务会被触发。由于系统常提前重回休眠或无网络,任务往往执行失败。我希望检测该darkwake状态并阻止同步任务运行,相关日志如下:
2024-11-25 21:22:38 +0100 Assertions PID 520(powerd) Created InternalPreventSleep "Holding in darkwake for up to 20 seconds to query model for inactivity prediction" 00:00:00 id:0x0xd0000856f [System: PrevIdle SRPrevSleep kCPU] 2024-11-25 21:22:38 +0100 Assertions PID 520(powerd) Released InternalPreventSleep "Holding in darkwake for up to 20 seconds to query model for inactivity prediction" 00:00:00 id:0x0xd0000856f [System: PrevIdle] 2024-11-25 21:22:38 +0100 Assertions PID 630(mDNSResponder) Created MaintenanceWake "mDNSResponder:maintenance" 00:00:00 id:0x0xd00008570 [System: PrevIdle]
解决方案
方法1:通过pmset命令检测状态
macOS自带的pmset工具能查询系统电源断言,其中包含darkwake相关标识。你可以在Dart里调用系统命令获取状态:
import 'dart:io'; Future<bool> isInDarkwake() async { try { final result = await Process.run('pmset', ['-g', 'assertions']); if (result.exitCode == 0) { final output = result.stdout.toString(); // 匹配日志里的darkwake相关特征 return output.contains('darkwake') || output.contains('SRPrevSleep') || output.contains('MaintenanceWake'); } } catch (e) { // 命令执行失败默认返回false,允许任务执行 return false; } return false; }
同步任务执行前调用这个方法,返回true就跳过任务:
Timer.periodic(Duration(minutes: 10), (timer) async { if (await isInDarkwake()) { print('当前处于darkwake状态,跳过同步任务'); return; } // 执行同步逻辑 await syncWithServer(); });
方法2:监听系统电源通知
macOS有电源状态变化的通知机制,你可以通过Flutter的原生通道来监听,提前获知darkwake状态:
- macOS原生端(Swift):注册监听,检测到darkwake时通知Dart层
import Cocoa import FlutterMacOS class MainFlutterWindow: NSWindow { override func awakeFromNib() { let flutterViewController = FlutterViewController.init() let windowFrame = self.frame self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) let channel = FlutterMethodChannel(name: "com.example.power", binaryMessenger: flutterViewController.engine.binaryMessenger) // 监听电源状态通知 NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "IOPMPowerSourceNotification"), object: nil, queue: nil) { notification in if let info = notification.userInfo, let isDarkwake = info["DarkWake"] as? Bool { channel.invokeMethod("onDarkwakeStateChanged", arguments: isDarkwake) } } super.awakeFromNib() } }
- Dart层:接收回调并维护状态
import 'package:flutter/services.dart'; bool _isInDarkwake = false; void setupPowerListener() { const channel = MethodChannel('com.example.power'); channel.setMethodCallHandler((call) async { if (call.method == 'onDarkwakeStateChanged') { _isInDarkwake = call.arguments as bool; } }); } // 任务中使用状态判断 Timer.periodic(Duration(minutes: 10), (timer) async { if (_isInDarkwake) { print('当前处于darkwake状态,跳过同步任务'); return; } await syncWithServer(); });
方法3:结合网络可达性检测
除了检测darkwake,还可以额外判断网络是否可用,双重避免任务失败:
import 'package:connectivity_plus/connectivity_plus.dart'; Future<bool> canPerformSync() async { final isDarkwake = await isInDarkwake(); if (isDarkwake) return false; final connectivityResult = await Connectivity().checkConnectivity(); return connectivityResult != ConnectivityResult.none; }
内容的提问来源于stack exchange,提问作者damnation
相关产品推荐
相关产品推荐

