mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
fix: safe scan notifications
ref:
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import '../models/device_info.dart';
|
||||
@@ -461,7 +462,7 @@ class ConnectionProvider with ChangeNotifier {
|
||||
_isScanning = true;
|
||||
_scannedDevices.clear();
|
||||
_error = null;
|
||||
notifyListeners();
|
||||
_notifyListenersSafely();
|
||||
debugPrint('✅ [Provider] Scan state initialized, notifying listeners');
|
||||
|
||||
try {
|
||||
@@ -477,7 +478,7 @@ class ConnectionProvider with ChangeNotifier {
|
||||
debugPrint(
|
||||
'✅ [Provider] Added device to list: ${device.platformName} (RSSI: $rssi dBm), total: ${_scannedDevices.length}',
|
||||
);
|
||||
notifyListeners();
|
||||
_notifyListenersSafely();
|
||||
} else {
|
||||
// Update RSSI if device already exists
|
||||
final index = _scannedDevices.indexWhere(
|
||||
@@ -488,7 +489,7 @@ class ConnectionProvider with ChangeNotifier {
|
||||
debugPrint(
|
||||
' 🔄 [Provider] Updated RSSI for ${device.platformName}: $rssi dBm',
|
||||
);
|
||||
notifyListeners();
|
||||
_notifyListenersSafely();
|
||||
} else {
|
||||
debugPrint(
|
||||
' ⏭️ [Provider] Device already in list with same RSSI, skipping',
|
||||
@@ -502,7 +503,7 @@ class ConnectionProvider with ChangeNotifier {
|
||||
} finally {
|
||||
debugPrint('🏁 [Provider] Scan completed');
|
||||
_isScanning = false;
|
||||
notifyListeners();
|
||||
_notifyListenersSafely();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,6 +511,18 @@ class ConnectionProvider with ChangeNotifier {
|
||||
Future<void> stopScan() async {
|
||||
await FlutterBluePlus.stopScan();
|
||||
_isScanning = false;
|
||||
_notifyListenersSafely();
|
||||
}
|
||||
|
||||
void _notifyListenersSafely() {
|
||||
final phase = SchedulerBinding.instance.schedulerPhase;
|
||||
if (phase == SchedulerPhase.transientCallbacks ||
|
||||
phase == SchedulerPhase.persistentCallbacks) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
notifyListeners();
|
||||
});
|
||||
return;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ class ConnectionDialog extends StatefulWidget {
|
||||
class _ConnectionDialogState extends State<ConnectionDialog>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late TabController _tabController;
|
||||
late final ConnectionProvider _connectionProvider;
|
||||
final NetworkScannerService _networkScanner = NetworkScannerService();
|
||||
final List<DiscoveredServer> _discoveredServers = [];
|
||||
int _scannedCount = 0;
|
||||
@@ -46,16 +47,13 @@ class _ConnectionDialogState extends State<ConnectionDialog>
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(length: 2, vsync: this);
|
||||
_connectionProvider = Provider.of<ConnectionProvider>(context, listen: false);
|
||||
|
||||
// Defer scan startup until after the first frame so Provider listeners
|
||||
// are not notified while this dialog is still being built.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
final connectionProvider = Provider.of<ConnectionProvider>(
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
connectionProvider.startScan();
|
||||
_connectionProvider.startScan();
|
||||
});
|
||||
|
||||
// Set up network scanner callbacks
|
||||
@@ -85,11 +83,7 @@ class _ConnectionDialogState extends State<ConnectionDialog>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
final connectionProvider = Provider.of<ConnectionProvider>(
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
connectionProvider.stopScan();
|
||||
_connectionProvider.stopScan();
|
||||
_networkScanner.stopScan();
|
||||
// Remove listener before disposing to prevent memory leaks
|
||||
_tabController.removeListener(_onTabChanged);
|
||||
|
||||
Reference in New Issue
Block a user