深入了解Flutter的isolate(4) --- 使用isolates的方法

栏目: IOS · Android · 发布时间: 6年前

内容简介:前面讲了如何创建isolate,这篇文章讲创建了isolate之后,isolate之间如何通信。isolates之间通信方法有两种:Compute函数对isolate的创建和底层的消息传递进行了封装,使得我们不必关系底层的实现,只需要关注功能实现。

前面讲了如何创建isolate,这篇文章讲创建了isolate之后,isolate之间如何通信。

0x01 isolates之间通信方法

isolates之间通信方法有两种:

  1. 高级API:Compute函数 (用起来方便)
  2. 低级API:ReceivePort

0x02 Compute函数

Compute函数对isolate的创建和底层的消息传递进行了封装,使得我们不必关系底层的实现,只需要关注功能实现。

首先我们需要:

  1. 一个函数:必须是顶级函数或静态函数
  2. 一个参数:这个参数是上面的函数定义入参(函数没有参数的话就没有)

比如,还是计算斐波那契数列:

void main() async{
  //调用compute函数,compute函数的参数就是想要在isolate里运行的函数,和这个函数需要的参数
  print( await compute(syncFibonacci, 20));
  runApp(MyApp());
}

int syncFibonacci(int n){
  return n < 2 ? n : syncFibonacci(n-2) + syncFibonacci(n-1);
}
复制代码

运行后的结果如下:

flutter: 6765
复制代码

是不是很简单,接下来看下 compute 函数的源码,这里的代码有点复杂,会把分析的添加到代码的注释里,首先介绍一个 compute 函数里用到的函数别名:

ComputeCallback<Q, R> 定义如下:

// Q R是泛型,ComputeCallback是一个有参数Q,返回值为R的函数
typedef ComputeCallback<Q, R> = R Function(Q message);
复制代码

正式看源码:

//compute函数 必选参数两个,已经讲过了
Future<R> compute<Q, R>(ComputeCallback<Q, R> callback, Q message, { String debugLabel }) async {
  //如果是在profile模式下,debugLabel为空的话,就取callback.toString()
  profile(() { debugLabel ??= callback.toString(); });
  final Flow flow = Flow.begin();
  Timeline.startSync('$debugLabel: start', flow: flow);
  final ReceivePort resultPort = ReceivePort();
  Timeline.finishSync();
  //创建isolate,这个和前面讲的创建isolate的方法一致
  //还有一个,这里传过去的参数是用_IsolateConfiguration封装的类
  final Isolate isolate = await Isolate.spawn<_IsolateConfiguration<Q, R>>(
    _spawn,
    _IsolateConfiguration<Q, R>(
      callback,
      message,
      resultPort.sendPort,
      debugLabel,
      flow.id,
    ),
    errorsAreFatal: true,
    onExit: resultPort.sendPort,
  );
  final R result = await resultPort.first;
  Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id));
  resultPort.close();
  isolate.kill();
  Timeline.finishSync();
  return result;
}

@immutable
class _IsolateConfiguration<Q, R> {
  const _IsolateConfiguration(
    this.callback,
    this.message,
    this.resultPort,
    this.debugLabel,
    this.flowId,
  );
  final ComputeCallback<Q, R> callback;
  final Q message;
  final SendPort resultPort;
  final String debugLabel;
  final int flowId;

  R apply() => callback(message);
}

void _spawn<Q, R>(_IsolateConfiguration<Q, R> configuration) {
  R result;
  Timeline.timeSync(
    '${configuration.debugLabel}',
    () {
      result = configuration.apply();
    },
    flow: Flow.step(configuration.flowId),
  );
  Timeline.timeSync(
    '${configuration.debugLabel}: returning result',
    () { configuration.resultPort.send(result); },
    flow: Flow.step(configuration.flowId),
  );
}

## 0x03 ReceivePort
复制代码

import 'dart:async'; import 'dart:io'; import 'dart:isolate';

import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart';

//一个普普通通的Flutter应用的入口 //main函数这里有async关键字,是因为创建的isolate是异步的 void main() async{ runApp(MyApp());

//asyncFibonacci函数里会创建一个isolate,并返回运行结果 print(await asyncFibonacci(20)); }

//这里以计算斐波那契数列为例,返回的值是Future,因为是异步的 Future asyncFibonacci(int n) async{ //首先创建一个ReceivePort,为什么要创建这个? //因为创建isolate所需的参数,必须要有SendPort,SendPort需要ReceivePort来创建 final response = new ReceivePort(); //开始创建isolate,Isolate.spawn函数是isolate.dart里的代码,_isolate是我们自己实现的函数 //_isolate是创建isolate必须要的参数。 await Isolate.spawn(_isolate,response.sendPort); //获取sendPort来发送数据 final sendPort = await response.first as SendPort; //接收消息的ReceivePort final answer = new ReceivePort(); //发送数据 sendPort.send([n,answer.sendPort]); //获得数据并返回 return answer.first; }

//创建isolate必须要的参数 void _isolate(SendPort initialReplyTo){ final port = new ReceivePort(); //绑定 initialReplyTo.send(port.sendPort); //监听 port.listen((message){ //获取数据并解析 final data = message[0] as int; final send = message[1] as SendPort; //返回结果 send.send(syncFibonacci(data)); }); }

int syncFibonacci(int n){ return n < 2 ? n : syncFibonacci(n-2) + syncFibonacci(n-1); }

复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTTP Essentials

HTTP Essentials

Stephen A. Thomas、Stephen Thomas / Wiley / 2001-03-08 / USD 34.99

The first complete reference guide to the essential Web protocol As applications and services converge and Web technologies not only assume HTTP but require developers to manipulate it, it is be......一起来看看 《HTTP Essentials》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具