如何避免在繁重的计算中冻结 UI

How to avoid freezing the UI on heavy computation

正在尝试使用拦截器从服务器(来自 dio)解密 JSON。但是 UI 在解密过程中冻结。

class DecryptInterceptor extends Interceptor {

  @override
  Future onResponse(Response response) async {
    response.data = decrypt(response.data); //freezes here
    return super.onResponse(response);
  }

}

Object decrypt(Object object){
  // computations
}

你可以使用 flutter 提供的 compute 属性 在另一个 isolate 中执行任务。它正是为此类任务而存在的。

class DecryptInterceptor extends Interceptor {
  @override
  Future onResponse(Response response) async {
    response.data =await compute(decrypt,response.data); //freezes here
    return super.onResponse(response);
  }
}
  Object decrypt(Object object){
    return result;
  }

虽然对于您可以传入参数并作为结果检索的数据类型,它有一些限制。您可以了解更多 here.

异步编程范式基于单线程模型。异步通过不等待 I/O 任务完成来优化 CPU 使用。相反,它对任务进行回调并告诉它“完成后调用它”。现在它可以在任务完成并调用回调时处理其他工作。当任务是 HTTP 请求或文件操作时,这是有意义的,因为这些将由其他设备而不是 CPU 处理。但是,如果任务 CPU 密集,那么使用异步将无济于事。

你可以看看Isolate,相当于Dart中的thread。您可以创建一个单独的隔离区,运行 在那里完成繁重的任务。

还有compute()方法。它接受一个函数和参数,然后在一个单独的 isolate 上使用提供的参数对该函数求值,returns 结果为 Future。这要容易得多,并且可以完成工作。

一个CPU密集的虚拟方法:

int heavyTask(int n) {
  int z = n;
  for (var i = 0; i < n; i++) {
    i % 2 == 0 ? z-- : z += 3;
  }
  return z + n;
}

使用 compute() 方法 运行 它在一个单独的 isolate 上:

 compute(heavyTask, 455553000)
     .then((res) => print("result is $res"));