在onTap事件中,执行耗时操作ui阻塞,比如在onTap上传多张大照片。
这里我们用sleep代替耗时操作
Future slp(t) async{
sleep(Duration(seconds:t));
return 'time out';
}
onTap(){
slp(5);
}
ui就会卡住5秒,无响应。
一开始我就使用Future、async、await去做异步操作,以为这样能解决问题,经过一天研究发现他们都还在同一个线程里面,也就是UI线程,导致卡顿,这明显不是我们想要的异步加载数据。
Dart真正的线程叫隔离(Isolate)
那么我们怎么解决这个问题呢,其实很简单,我们知道卡顿的原因是在同一个线程中导致的,那我们有没有办法将计算移到新的线程中呢,当然是可以的。不过在dart中,这里不是称呼线程,是Isolate,直译叫做隔离,这么古怪的名字,是因为隔离不共享数据,每个隔离中的变量都是不同的,不能相互共享。
但是由于dart中的Isolate比较重量级,UI线程和Isolate中的数据的传输比较复杂,因此flutter为了简化用户代码,在foundation库中封装了一个轻量级compute操作,我们先看看compute,然后再来看Isolate。
要使用compute,必须注意的有两点,一是我们的compute中运行的函数,必须是顶级函数或者是static函数,二是compute传参,只能传递一个参数,返回值也只有一个,我们先看看本例中的compute优化吧:
#函数说明
#func函数必须是顶级函数 或 static修饰的函数
#arg可以是任何,包括int,string,map等
compute(func, arg);
真的很简单,只用在使用的时候,放到compute函数中就行了。
完整代码:
import 'package:flutter/foundation.dart';
static slp(t){
sleep(Duration(seconds:t));
return 'slp123';
}
onTap1(){
compute(slp,5).then((value) => print(value));
//打印出:slp123
}
onTap2() async{
var value = await compute(slp,5);
print(value);//打印出:slp123
}
这样改造后,onTap事件执行耗时操作就不会阻塞ui了
网友评论