Flutter基础(Isolate)

发布于:2025-06-30 ⋅ 阅读:(17) ⋅ 点赞:(0)

🧱 1. ​​Isolate 是什么?—— “独立的小房间”​

  • ​每个 Isolate 都是独立运行的​​:就像公司里每个员工有自己的办公室,互不干扰。一个房间卡住了(比如计算太复杂),其他房间照样工作。
  • ​不共享内存​​:员工之间不能直接翻对方的文件柜(内存隔离),只能通过“传纸条”(消息传递)沟通。
  • ​解决卡顿问题​​:Flutter 的 UI 在主 Isolate(主线程)运行,如果主房间在干重活(如解析大文件),UI 就会卡住。这时把重活扔给另一个 Isolate,UI 就流畅了。

⚙️ 2. ​​为什么需要 Isolate?—— “不让主线程累趴”​

  • ​主线程负责 UI​​:所有按钮点击、动画渲染都在主线程跑。
  • ​耗时任务会阻塞 UI​​:比如计算 1 亿次加法、读取超大文件、处理图像。这些任务如果在主线程跑,App 就卡成幻灯片。
  • ​Isolate 的用途​​:把这些耗时任务丢到另一个 Isolate 后台执行,主线程继续流畅响应用户操作。

🛠️ 3. ​​怎么用 Isolate?—— “两种开小号方式”​

(1) ​​手动创建:Isolate.spawn()

适合复杂任务,需要自己管理消息传递:

import 'dart:isolate';

// 后台任务函数(必须是静态函数或全局函数)
void backgroundTask(SendPort sendPort) {
  int result = 0;
  for (int i = 0; i < 1000000000; i++) {
    result += i; // 模拟耗时计算
  }
  sendPort.send(result); // 把结果传回主线程
}

void main() async {
  ReceivePort receivePort = ReceivePort(); // 主线程的“收件箱”
  await Isolate.spawn(backgroundTask, receivePort.sendPort); // 启动新 Isolate
  
  // 监听结果
  receivePort.listen((result) {
    print("计算结果:$result");
    receivePort.close(); // 关闭收件箱
  });
}

处理两个任务的代码

import 'dart:async';
import 'dart:isolate';
import 'package:flutter/material.dart';

// 任务1:模拟图像处理(高斯模糊)
Future<String> _processImage(String imagePath) async {
  await Future.delayed(const Duration(seconds: 2)); // 模拟耗时
  return "处理成功: ${imagePath.split('/').last} (模糊度: 10px)";
}

// 任务2:模拟网络请求(获取用户数据)
Future<String> _fetchUserData(int userId) async {
  await Future.delayed(const Duration(seconds: 3)); // 模拟网络延迟
  if (userId > 100) throw Exception("用户ID无效");
  return "用户数据: {id: $userId, name: '用户$userId'}";
}

// 启动两个 Isolate 并汇总结果
Future<Map<String, dynamic>> runParallelTasks() async {
  final ReceivePort resultPort = ReceivePort();
  final Completer<Map<String, dynamic>> completer = Completer();

  // 错误收集器
  final errors = {};

  // 任务计数器
  int completedCount = 0;
  const totalTasks = 2;

  resultPort.listen((message) {
    if (message is Map) {
      final String taskType = message['type'];
      if (message.containsKey('result')) {
        completer.isCompleted
            ? null
            : completer.complete({...completer.future.then((v) => v) ?? {}, taskType: message['result']});
      } else if (message.containsKey('error')) {
        errors[taskType] = message['error'];
      }
      completedCount++;
    }

    // 所有任务完成(成功或失败)
    if (completedCount == totalTasks) {
      resultPort.close();
      if (errors.isNotEmpty) completer.completeError(errors);
    }
  });

  // 启动图像处理 Isolate
  Isolate.spawn(
    _isolateTaskHandler,
    {
      'type': 'image',
      'task': () => _processImage('assets/images/photo.jpg'),
      'sendPort': resultPort.sendPort,
    },
  );

  // 启动网络请求 Isolate
  Isolate.spawn(
    _isolateTaskHandler,
    {
      'type': 'network',
      'task': () => _fetchUserData(200), // 此处故意传入错误ID触发异常
      'sendPort': resultPort.sendPort,
    },
  );

  return completer.future;
}

// Isolate 任务处理器
void _isolateTaskHandler(Map<String, dynamic> message) async {
  final String type = message['type'];
  final Function task = message['task'];
  final SendPort sendPort = message['sendPort'];

  try {
    final result = await task();
    sendPort.send({'type': type, 'result': result});
  } catch (e) {
    sendPort.send({'type': type, 'error': e.toString()});
  }
}

// 界面组件
class ParallelIsolateDemo extends StatefulWidget {
  const ParallelIsolateDemo({super.key});

  @override
  State<ParallelIsolateDemo> createState() => _ParallelIsolateDemoState();
}

class _ParallelIsolateDemoState extends State<ParallelIsolateDemo> {
  Map<String, dynamic>? _results;
  String? _error;

  void _startTasks() async {
    setState(() {
      _results = null;
      _error = null;
    });

    try {
      final results = await runParallelTasks();
      setState(() => _results = results);
    } catch (e) {
      setState(() => _error = "错误: ${e.toString()}");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('双任务并行 Isolate')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _startTasks,
              child: const Text('启动双任务'),
            ),
            const SizedBox(height: 20),
            if (_results != null) ...[
              Text('图像结果: ${_results!['image']}'),
              Text('网络结果: ${_results!['network']}'),
            ],
            if (_error != null)
              Text(_error!, style: const TextStyle(color: Colors.red)),
          ],
        ),
      ),
    );
  }
}

// 应用入口
void main() => runApp(
      MaterialApp(
        home: Scaffold(body: Center(child: ParallelIsolateDemo())),
      ),
    );


网站公告

今日签到

点亮在社区的每一天
去签到