Flutter的任务队列与Dart语法
Dart语法
背景
由于同时进行多个项目,不同项目之间使用不同的语言,如Java,Dart,Javascript,Kotlin。每种语言之间虽然大体相同,但还是有一些细节差异,为了提升开发效率,总结Dart的语法差异点并记忆。
关键点
- 一切都是对象,数字,方法,null都是对象,对象都继承于object
- 入口函数为main(),支持函数式编程
- 如何定义私有类和私有变量:标识符以 (_) 开头,则该标识符 在库内是私有的
- 变量定义:
- 不指名类型:var name;
- 指定类型:String name;
- 所有变量的默认值是null
- 定义常量:final 或 const,const为编译时常量
- 类型:
- num类型:int,double
- 字符串:
- 单引号,双引号都可以
- 支持表达式:’${s.toUpperCase()} is very handy!’
- 多行字符串:三个单引号 或 三个双引号
- 布尔类型:
- bool,true, false
- 只有为true时,才是真,其他都为false
- 数据与列表:List
- 创建:List list = [1, 2, 3];
- 长度:length属性
- Key-Value:Map
- 创建:Map map = {key:value};
- 赋值:map[‘key’] = ‘value’;
- 长度:length属性
- 方法:
- 方法也是对象,对应Function类
- 定义:返回值 方法名(参数){}
- 命名参数:
- 定义:{bool bold, bool hidden}
- 使用:enableFlags(bold: true, hidden: false);
- 可选参数:
- 定义:[String device]
- 使用:可不传入
- 匿名函数 或 lambda 或者 closure闭包
- 定义:(参数){},简写:(参数) => 一行语句
- 类型判断:
- 类型转换:as
- 类型判断:is,is!
Flutter的任务队列
背景
Flutter是默认是单线程+两个队列,所有的Future都运行在UI线程里,即主Isolate里,对于真正需要异步的任务,可以通过compute()来实现,由于compute方法,每次都是创建一个新的isolate,极端情况下,同时可能会有多个isolate运行。
需求:是否能实现类似线程池的能力,能整体控制同时运行的isolate数量
思路与实现
经过测试,发现Flutter有如下限制:
- Isolate只有在创建时,通过spawn()方法,才能传递方法对象,isolate创建后,不能传递方法对象
- Isolate不支持反射库 —- 为了保证‘tree-shaking’的效果
- 两个Isolate之间,不共享内存,所以无法通过单例共享数据,由于httpclient本身已经在异步执行,为了httpclient能获取CommonHeader,不要把httpclient请求放在异步isolate里
实现思路:把任务保存到Queue队列里,整理控制Isolate的数量,如后台同时只能运行一个isolate
难点:
- 任务进入队列后,如果通知调用方?—- 通过查看compute()源码得知:通过Completer
- 队列里的传入类型不确定,无法使用泛型?—– 去掉compute()的泛型,整体使用dynamic
DioManager管理类:
1 | class _Task { |
_isolate_io类:通过修改compute源码实现
1 | Future<dynamic> compute(Function callback, dynamic message, Completer<dynamic> result) async { |