flutter - 如何避免在繁重的计算中冻结 UI
问题描述
尝试使用拦截器(来自dio)从服务器解密 JSON。但用户界面在解密期间冻结。
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
}
解决方案
异步编程范式基于单线程模型。异步通过不等待 I/O 任务完成来优化 CPU 使用率。相反,它对任务进行回调并告诉它“完成后调用它”。现在它可以在任务完成并调用回调时处理其他工作。当任务是 HTTP 请求或文件操作时,这是有道理的,因为这些将由其他设备而不是 CPU 处理。但是如果任务是 CPU 密集型的,那么使用 async 将无济于事。
你可以看看Isolate,相当于 Dart 中的线程。您可以创建一个单独的隔离并在那里运行您的繁重任务。
还有compute()
方法。它接受一个函数和参数,然后在单独的隔离中使用提供的参数评估该函数,并将结果返回为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()
方法在单独的隔离上运行它:
compute(heavyTask, 455553000)
.then((res) => print("result is $res"));
推荐阅读
- javascript - 使用 JavaScript 替换字符串中的 # 和 \s
- python - 每次两个值匹配时获取总和
- .net-core - DocFX(在 Azure DevOps 中):未找到导入的项目“\15.0\Microsoft.Common.props”
- php - 将两个不同函数的结果相乘
- javascript - index.html 不会在 chrome 浏览器中显示 main.js 代码
- javascript - 使用 Nodejs 渲染 html-css-javascript-images
- google-apps-script - 基于先前选择的 Google 表单问题
- c# - 如何在 Unity 中单击时从十六进制地图中获取坐标
- css - 在移动设备中重新排序列
- react-native - 抽屉导航器的 contentComponent 内的 stackNavigator