Flutter 多线程实现
异步Isolate实现多线程
最近在看Flutter开发相关知识点,对照着Android原生,探究了下多线程实现方式。在Flutter中有 Isolate,隔离,它的实现原理并不是内存共享的,它更像是一个进程。
最简单的 compute
import 'dart:convert';
main(List<String> args) {
String jsonString = '''{ "id":"1234", "name":"hahaha"}''';
People people = parseJson(jsonString);
print(people.name);
}
Student parseJson(String json) {
Map<String, dynamic> map = jsonDecode(json);
return People.fromJson(map);
}
class People{
String id;
String name;
People({this.id, this.name});
factory People.fromJson(Map parsedJson) {
return People(id: parsedJson['id'], name: parsedJson['name']);
}
}
我们需要把上面代码放入isolate中执行
isolate
Future<People> loadPeople(String json) {
return compute(parseJson, json);
}
Student parseJson(String json) {
Map<String, dynamic> map = jsonDecode(json);
return People.fromJson(map);
}
compute是 Flutter 的 api ,帮我们封装了 isolate,使用十分简单,但是也有局限性, 它没有办法多次返回结果,也没有办法持续性的传值计算,isolate了。这个有点像AIDL和Messager的关系。import 'dart:convert';
import 'dart:isolate';
main(List<String> args) async {
await start();
}
Isolate isolate;
start() async {
//创建接收端口,用来接收子线程消息
ReceivePort receivePort = ReceivePort();
//创建并发Isolate,并传入主线程发送端口
isolate = await Isolate.spawn(entryPoint, receivePort.sendPort);
//监听子线程消息
receivePort.listen((data) {
print('Data:$data');
});
}
//并发Isolate
entryPoint(SendPort sendPort) {
String jsonString = '''{ "id":"123", "name":"张三"}''';
People people = parseJson(jsonString);
sendPort.send(people);
}
Student parseJson(String json) {
Map<String, dynamic> map = jsonDecode(json);
return People.fromJson(map);
}
class people {
String id;
String name;
People({this.id, this.name});
factory People.fromJson(Map parsedJson) {
return People(id: parsedJson['id'], name: parsedJson['name']);
}
}
isolate,那么我们就需要实现双向通信:import 'dart:isolate';
main(List<String> args) async {
// 在主线程里面
await start();
await Future.delayed(Duration(seconds: 1), () {
threadPort.send('主线程');
print('1');
});
await Future.delayed(Duration(seconds: 1), () {
threadPort.send('我也来自主线程');
print('2');
});
await Future.delayed(Duration(seconds: 1), () {
threadPort.send('end');
print('3');
});
}
Isolate isolate;
//子线程发送端口
SendPort threadPort;
start() async {
// 在主线程
//创建主线程接收端口,用来接收子线程消息
ReceivePort receivePort = ReceivePort();
//创建并发Isolate,并传入主线程发送端口
isolate = await Isolate.spawn(entryPoint, receivePort.sendPort);
//监听子线程消息
receivePort.listen((data) {
print('主线程收到来自子线程的消息$data');
if (data is SendPort) {
threadPort = data;
}
});
}
//并发Isolate
entryPoint(dynamic message) {
// 在子线程里面
//创建子线程接收端口,用来接收主线程消息
ReceivePort receivePort = ReceivePort();
SendPort sendPort;
print('==entryPoint==$message');
if (message is SendPort) {
sendPort = message;
print('子线程开启');
sendPort.send(receivePort.sendPort);
//监听子线程消息
receivePort.listen((data) {
print('子线程收到来自主线程的消息$data');
assert(data is String);
if (data == 'end') {
isolate?.kill();
isolate = null;
print('子线程结束');
return;
}
});
return;
}
}
双向通信比较复杂,所以我们需要封装下,通过 api 让外部调用:
import 'dart:async';
import 'dart:isolate';
main(List<String> args) async {
var worker = Worker();
worker.reuqest('发送消息1').then((data) {
print('子线程处理后的消息:$data');
});
Future.delayed(Duration(seconds: 2), () {
worker.reuqest('发送消息2').then((data) {
print('子线程处理后的消息:$data');
});
});
}
class Worker {
SendPort _sendPort;
Isolate _isolate;
final _isolateReady = Completer<void>();
final Map<Capability, Completer> _completers = {};
Worker() {
init();
}
void dispose() {
_isolate.kill();
}
Future reuqest(dynamic message) async {
await _isolateReady.future;
final completer = new Completer();
final requestId = new Capability();
_completers[requestId] = completer;
_sendPort.send(new _Request(requestId, message));
return completer.future;
}
Future<void> init() async {
// 在主线程里面
final receivePort = ReceivePort();
final errorPort = ReceivePort();
errorPort.listen(print);
receivePort.listen(_handleMessage);
_isolate = await Isolate.spawn(
_isolateEntry,
receivePort.sendPort,
onError: errorPort.sendPort,
);
}
void _handleMessage(message) {
if (message is SendPort) {
_sendPort = message;
_isolateReady.complete();
return;
}
if (message is _Response) {
final completer = _completers[message.requestId];
if (completer == null) {
print("Invalid request ID received.");
} else if (message.success) {
completer.complete(message.message);
} else {
completer.completeError(message.message);
}
return;
}
throw UnimplementedError("Undefined behavior for message: $message");
}
static void _isolateEntry(dynamic message) {
// 在子线程里面
SendPort sendPort;
final receivePort = ReceivePort();
receivePort.listen((dynamic message) async {
if (message is _Request) {
print('子线程收到:${message.message}');
sendPort.send(_Response.ok(message.requestId, '处理后的消息'));
return;
}
});
if (message is SendPort) {
sendPort = message;
sendPort.send(receivePort.sendPort);
return;
}
}
}
class _Request {
/// The ID of the request so the response may be associated to the request's future completer.
final Capability requestId;
/// The actual message of the request.
final dynamic message;
const _Request(this.requestId, this.message);
}
class _Response {
/// The ID of the request this response is meant to.
final Capability requestId;
/// Indicates if the request succeeded.
final bool success;
/// If [success] is true, holds the response message.
/// Otherwise, holds the error that occured.
final dynamic message;
const _Response.ok(this.requestId, this.message) : success = true;
const _Response.error(this.requestId, this.message) : success = false;
}
Flutter 多线程实现的更多相关文章
- Android开发如何准备技术面试(含Android面试押题)
今年毋庸置疑是找工作的寒冬,每一个出来找工作的同学都是值得尊敬的.现在找工作,虽然略难,但是反过来看也会逼迫我们成为更加优秀的自己. 但是不管是旺季还是寒冬,有一些优秀的同学找工作还是挺顺利的.所以说 ...
- 双非本科字节跳动Android面试经验和心得体会分享(已拿offer)
新人报道,没有什么可分享的,就记录一些自己求职的体会和心得. 我是在校招补录的时候参加了今日头条的招聘,岗位是Android开发,最后成功拿到了入场券.但是这也丝毫不值得骄傲,大家都知道:技术日新月异 ...
- 2579页阿里P8Android学习笔记在互联网上火了,完整版开放下载
笔记作者:来自于阿里P8级大神: Mark 笔记特点:条理清晰,理论+实战+源码,含图像化表示更加易懂. 内容概要:Android 相关,性能优化,Java 相关,Kotlin 相关,网络相关,插件化 ...
- 2020年!最全Android大厂面试真题合集(附答案)
这份Android面试真题涵盖了图片,网络和安全机制,网络,数据库,插件化.模块化.组件化.热修复.增量更新.Gradle,架构设计和设计模式,Android Framework .Android优秀 ...
- 说实话,Android开发月薪3W,谁不酸呢?
近期有个网友在某匿名区晒字节跳动Offfer,毕业一年月薪3W,引发众多读者羡慕,纷纷留言酸了.酸了.但进大厂的要求还是蛮高的,需要在技术实力上有一定的积累,今天给大家分享一份高质量笔记, 助力大家技 ...
- Flutter 实现原理及在马蜂窝的跨平台开发实践
一直以来,跨平台开发都是困扰移动客户端开发的难题. 在马蜂窝旅游 App 很多业务场景里,我们尝试过一些主流的跨平台开发解决方案, 比如 WebView 和 React Native,来提升开发效率和 ...
- Flutter学习一
包管理 依赖本地包 dependencies: pkg1: path: ../../code/pkg1 依赖git包 dependencies: pkg1: git: url: git://githu ...
- Flutter中通过https post Json接收Json
Flutter 已然成为炙手可热前端框架.若问跨平台到底有多香,自然是要多香有多香.今天我就分享这些天研究Flutter http连接和json格式转换的内容,小弟对Flutter也是小白一名,如有错 ...
- Flutter 简介(事件、路由、异步请求)
1. 前言 Flutter是一个由谷歌开发的开源移动应用软件开发工具包,用于为Android和iOS开发应用,同时也将是Google Fuchsia下开发应用的主要工具.其官方编程语言为Dart. 同 ...
- iOS播放器、Flutter高仿书旗小说、卡片动画、二维码扫码、菜单弹窗效果等源码
iOS精选源码 全网最详细购物车强势来袭 一款优雅易用的微型菜单弹窗(类似QQ和微信右上角弹窗) swift, UITableView的动态拖动重排CCPCellDragger 高仿书旗小说 Flut ...
随机推荐
- 学习 Tensorflow 的困境与解药
我构建的预测模型 在过去的一段时间里我抓去了小宇宙内上万条播客节目的首日播放量的数据,并利用这些数据构建了一个用于预测播客节目播放量的模型.包含以下六个输入参数: 节目发布于一周中的哪一天 节目发布于 ...
- Visual Studio 2022的安装 - 编程手把手系列文章
工欲善其事,必先利其器. 今天讲的是编程开发工具Visual Studio 2022的安装.作为手把手系列的开始,需要先对进行编程所使用的工具进行了解.此博文从下面几个步骤入手,对VS 2022这个开 ...
- VK2C21A:抗干扰/抗噪/高稳定性LCD屏显示驱动,抗干扰LCD驱动段码屏芯片
产品型号:VK2C21A/B/C/D 产品品牌:VINKA/永嘉微/永嘉微电 封装形式:SOP28/24/20/16 产品年份:新年份 原厂直销,工程服务,技术支持,价格最具优势! VK2C21A/B ...
- 华为Push用户增长服务:精准触达,加速增长
速戳了解华为Push用户增长服务:通过精细化运营,助力开发者高效实现用户增长,提升用户活跃度和粘性! 合作咨询请点此链接 了解更多详情>> 访问华为开发者联盟官网 获取开发指导文档 华为移 ...
- std::thread 四:异步(async)
*:如果 std::async 中传递参数 std::lunnch::deferred ,就需要等待调用 get() 或者 wait() 才会执行,并且代码非子线程运行,而是在主线程中执行 #incl ...
- redis 简单整理——缓存设计[三十二]
前言 简单整理一下缓存设计. 正文 缓存的好处: ·加速读写:因为缓存通常都是全内存的(例如Redis.Memcache),而 存储层通常读写性能不够强悍(例如MySQL),通过缓存的使用可以有效 地 ...
- Linux systemd 定时任务
哈喽大家好,我是咸鱼. 说到 Linux 定时任务,大家用得最多的就是 crond 服务,但其实 systemd 也有类似的功能.我们不但可以通过 systemd 来管理服务,还能设置定时任务,那就是 ...
- Vue 项目 invalid host header 问题 配置 disableHostCheck:true报错
项目场景:解决 Vue 项目 invalid host header 问题disableHostCheck:true报错 问题描述使用内网穿透时出现 invalid host header找了好多都是 ...
- React的理解以及特性
一.是什么 React,用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案 遵循组件设计模式.声明式编程范式和函数式编程概念,以使前端应用程序更高效 使用虚拟DOM来有效地操作 ...
- 使用pycuda替换字符串,使用cuda替换字符串
写一个python的cuda程序,实现字符串列表的字符串替换,把所有的123替换成xinyuuliu 以下是一个简单的 Python CUDA 代码示例,用于实现字符串列表的字符串替换.它使用了 NV ...