美文网首页
在onTap事件中,执行耗时操作ui阻塞

在onTap事件中,执行耗时操作ui阻塞

作者: 晓函 | 来源:发表于2022-01-17 15:09 被阅读0次

    在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了

    相关文章

      网友评论

          本文标题:在onTap事件中,执行耗时操作ui阻塞

          本文链接:https://www.haomeiwen.com/subject/ubpchrtx.html