Feat: Stellt den BackgroundManager auf IsolateManager um

This commit is contained in:
2026-01-03 21:53:37 +01:00
parent baef163b68
commit 7b3a1cfac6
11 changed files with 15625 additions and 107 deletions

View File

@@ -1,19 +1,18 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'package:isolate_manager/isolate_manager.dart';
import 'package:workmanager/workmanager.dart';
import '../Tasks/generate_transactions_task.dart';
import '../Tasks/task.dart';
import 'port_controller.dart';
import '../Tasks/workers.dart';
import '../Tasks/workmanager_workers.dart';
/// Erstellt Hintergrundtasks und führt diese aus
class BackgroundTaskController {
/// Erstellt eine neue Instanz dieser Klasse
BackgroundTaskController() {
if (Platform.isAndroid) {
if (!kIsWeb && Platform.isAndroid) {
unawaited(Workmanager().initialize(callbackDispatcher));
unawaited(
Workmanager().registerPeriodicTask(
@@ -25,47 +24,12 @@ class BackgroundTaskController {
);
} else {
unawaited(
Isolate.run(() {
unawaited(_runTask(
GenerateTransactionsTask(),
const Duration(minutes: 1),
const Duration(minutes: 30),
));
IsolateManager.runFunction(runTask, {
'taskName': 'generate_transactions',
'initialDelayMinutes': 1,
'frequencyMinutes': 30,
}),
);
}
}
Future<void> _runTask(
final Task task,
final Duration initialDelay,
final Duration frequency,
) async {
await Future.delayed(initialDelay);
final RootIsolateToken? rootIsolateToken = await PortController()
.getRootIsolateToken();
if (rootIsolateToken != null) {
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
await GenerateTransactionsTask().execute();
}
await Future.delayed(frequency);
unawaited(_runTask(task, initialDelay, frequency));
}
}
/// Die Funktion wird von Hintergrundtasks ausgerufen, um diese auszuführen
@pragma('vm:entry-point')
void callbackDispatcher() {
Workmanager().executeTask((final task, final inputData) {
switch (task) {
case 'generate_transactions':
return GenerateTransactionsTask().execute();
}
return Future.value(true);
});
}

View File

@@ -2,24 +2,28 @@ import 'dart:async';
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:logger/logger.dart';
/// Ein PortController mit verschiedenen FUnktionen zur KOmmunikations zwischen
/// Ein PortController mit verschiedenen Funktionen zur Kommunikation zwischen
/// main und anderen Isolates
class PortController {
/// Gibt eine Instanz dieser Klasse zurück
factory PortController() => _instance;
PortController._internal() {
if (ServicesBinding.rootIsolateToken != null) {
if (!kIsWeb && ServicesBinding.rootIsolateToken != null) {
_registerRootIsolateTokenSender();
}
}
static final PortController _instance = PortController._internal();
final Logger _logger = Logger();
/// Fügt einen Port mit [name] zum NameServer hinzu
void addPort(final SendPort sendPort, final String name) {
IsolateNameServer.removePortNameMapping(name);
IsolateNameServer.registerPortWithName(sendPort, name);
}
@@ -29,6 +33,8 @@ class PortController {
/// Gibt das [RootIsolateToken] der main-Isolate zurück
Future<RootIsolateToken?> getRootIsolateToken() async {
_logger.d('Trying to retrieve RootIsolateToken...');
final ReceivePort receivePort = ReceivePort();
final SendPort? rootPort = IsolateNameServer.lookupPortByName(
@@ -36,21 +42,26 @@ class PortController {
);
if (rootPort == null) {
_logger.e("Couldn't get Port from IsolateNameServer!");
receivePort.close();
return null;
}
_logger.i('Sending communication attempt...');
rootPort.send(receivePort.sendPort);
try {
final dynamic message = await receivePort.first;
if (message is RootIsolateToken) {
_logger.i('Got RootIsolateToken, returning...');
return message;
}
_logger.w("Couldn't get RootIsolateToken!");
return null;
} finally {
_logger.i('Closing receivePort...');
receivePort.close();
}
}
@@ -58,6 +69,8 @@ class PortController {
void _registerRootIsolateTokenSender() {
final ReceivePort receivePort = ReceivePort()
..listen((final value) {
_logger.d('Received Message with $value');
if (value is SendPort) {
value.send(ServicesBinding.rootIsolateToken);
}