Какие знаешь механизмы для запуска задач в фоне?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Механизмы запуска фоновых задач в Flutter
Flutter предоставляет несколько механизмов для выполнения задач в фоне, от простых до сложных. Выбор механизма зависит от типа задачи, её продолжительности и требований к надежности.
1. Isolate
Isolate — это основной механизм для выполнения кода в отдельном потоке без блокировки UI:
import "dart:isolate";
void heavyTask(SendPort sendPort) {
int result = 0;
for (int i = 0; i < 1000000; i++) {
result += i;
}
sendPort.send(result);
}
Future<void> runInIsolate() async {
final receivePort = ReceivePort();
await Isolate.spawn(heavyTask, receivePort.sendPort);
final result = await receivePort.first;
print("Результат: $result");
}
Преимущества:
- Полностью изолированный поток (нет конфликтов по памяти)
- Идеален для тяжелых вычислений
- Не блокирует UI
Недостатки:
- Нельзя напрямую делиться объектами
- Требует передачи данных через SendPort/ReceivePort
- Нельзя обновлять UI прямо из isolate
2. async/await с Future
Для менее требовательных задач используется стандартный Future:
Future<void> networkRequest() async {
try {
final response = await http.get(Uri.parse("https://api.example.com"));
print("Ответ: ${response.body}");
} catch (e) {
print("Ошибка: $e");
}
}
// Вызов без ожидания
networkRequest();
Когда использовать:
- Сетевые запросы
- Чтение файлов
- Операции с БД
3. compute() функция
compute() — удобная обертка над Isolate для простых функций:
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
Future<void> calculateFib() async {
final result = await compute(fibonacci, 30);
print("Результат: $result");
}
Преимущества:
- Проще чем Isolate
- Автоматическое управление портами
- Идеален для одноразовых вычислений
4. Фоновые сервисы (Platform Channels)
Для задач, которые должны продолжаться после закрытия приложения, используются native background services:
Android (WorkManager)
import "package:workmanager/workmanager.dart";
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
print("Выполняю фоновую задачу");
return Future.value(true);
});
}
void scheduleBackgroundTask() {
Workmanager().registerPeriodicTask(
"uniqueName",
"taskName",
frequency: Duration(minutes: 15),
);
}
iOS (Background Modes)
Для iOS требуется конфигурация в ios/Runner/Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
</array>
5. Timer и periodic задачи
Для регулярных задач используется Timer:
final timer = Timer.periodic(Duration(seconds: 5), (timer) {
print("Выполняю периодическую задачу");
// Отмена
if (someCondition) {
timer.cancel();
}
});
6. Streams
Stream позволяет обрабатывать непрерывный поток данных:
Stream<int> countStream() async* {
for (int i = 0; i < 10; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
// Использование
countStream().listen((value) {
print("Значение: $value");
});
7. GetX для управления async задачами
Популярный пакет GetX предоставляет удобный способ:
class MyController extends GetxController {
RxBool isLoading = false.obs;
void fetchData() async {
isLoading.value = true;
try {
// async операция
await Future.delayed(Duration(seconds: 2));
} finally {
isLoading.value = false;
}
}
}
Сравнительная таблица
| Механизм | Использование | Сложность |
|---|---|---|
| Future/async | Одна операция | Низкая |
| Isolate | Тяжелые вычисления | Средняя |
| compute() | Простые функции | Низкая |
| Timer | Периодические задачи | Низкая |
| Stream | Потоки данных | Средняя |
| WorkManager | Фоновые сервисы | Высокая |
Практический пример: загрузка больших файлов
Future<void> downloadLargeFile() async {
final url = "https://example.com/large-file.zip";
final dio = Dio();
try {
await dio.download(
url,
"${(await getTemporaryDirectory()).path}/file.zip",
onReceiveProgress: (received, total) {
final progress = (received / total * 100).toStringAsFixed(0);
print("Загружено: $progress%");
},
);
} catch (e) {
print("Ошибка: $e");
}
}
Итоги
Выбор механизма зависит от требований:
- Простые async операции → Future/async-await
- Тяжелые вычисления → Isolate или compute()
- Периодические задачи → Timer
- Потоки данных → Stream
- Фоновые сервисы → WorkManager/Background Modes
- UI-bound операции → обычные Future с setState()