fix: lifecycle

This commit is contained in:
2026-05-05 22:01:22 +02:00
parent 0da0905697
commit 30b25784c1
3 changed files with 53 additions and 16 deletions

View File

@ -26,8 +26,10 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
static const Duration _bootloaderScanTimeout = Duration(seconds: 10);
StreamSubscription<List<DiscoveredDevice>>? _scanSubscription;
BluetoothController? _bluetooth;
DiscoveredDevice? _dfuDevice;
bool _isBootloaderScanStarting = false;
bool _isDisposed = false;
@override
void initState() {
@ -37,8 +39,8 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
@override
void dispose() {
final bluetooth = ref.read(bluetoothProvider).valueOrNull;
unawaited(_scanSubscription?.cancel());
_isDisposed = true;
final bluetooth = _bluetooth;
unawaited(_stopBootloaderScan(bluetooth));
super.dispose();
}
@ -52,14 +54,19 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
try {
final bluetooth = await ref.read(bluetoothProvider.future);
if (!mounted) {
if (!mounted || _isDisposed) {
return;
}
_bluetooth = bluetooth;
final scanResult = await bluetooth.startScan(
timeout: _bootloaderScanTimeout,
scanMode: ScanMode.lowLatency,
);
if (!mounted || _isDisposed) {
await bluetooth.stopScan();
return;
}
if (scanResult.isErr()) {
return;
}
@ -74,20 +81,22 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
}
Future<void> _stopBootloaderScan([BluetoothController? bluetooth]) async {
await _scanSubscription?.cancel();
final subscription = _scanSubscription;
_scanSubscription = null;
await subscription?.cancel();
await bluetooth?.stopScan();
}
void _updateBootloaderDevice(List<DiscoveredDevice> devices) {
if (_isDisposed || !mounted) {
return;
}
final dfuDevice = devices.cast<DiscoveredDevice?>().firstWhere(
(device) => device != null && _isBootloaderAdvertisement(device),
orElse: () => null,
);
if (!mounted) {
return;
}
if (dfuDevice == null) {
_clearBootloaderDevice();
@ -104,7 +113,7 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
}
void _clearBootloaderDevice() {
if (!mounted || _dfuDevice == null) {
if (_isDisposed || !mounted || _dfuDevice == null) {
return;
}
@ -139,12 +148,12 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
builder: (_) => _BootloaderRecoverySetupPage(device: device),
),
);
if (!mounted || firmware == null) {
if (!mounted || _isDisposed || firmware == null) {
return;
}
await _stopBootloaderScan();
if (!mounted) {
if (!mounted || _isDisposed) {
return;
}
_clearBootloaderDevice();