网易首页 > 网易号 > 正文 申请入驻

FlutterComponent最佳实践之Timer的妙用

0
分享至

点击上方蓝字关注我,知识会给你力量

Timer在Flutter中,通常是用来构建延时的异步任务的,在讲解它的妙之前,我们先来看看Timer的基操。

Timer基操

Timer广义上可以理解为一个倒计时器,它从创建到结束会经历下面三个过程:

  • Creates a timer

  • Executes a callback

  • The timer finishes

创建一个Timer非常简单。

final timer = Timer(
const Duration(seconds: 3),
// TODO
},

上面这段代码,就代表着3秒延迟后执行回调闭包,当前代码中,这个回调只会执行一次。

那么如果我们需要创建一个周期性的计时器的话,就需要使用Timer.periodic构造函数。

final periodicTimer = Timer.periodic(
const Duration(seconds: 1),
(timer) {
// TODO
},

默认的周期性Timer会无限制的执行下去,所以,和所有的资源一样,我们需要对其进行管理,释放掉不使用的Timer资源。

❝ 通常我们会在Widget的dispose方法中释放。 ❞

首先就是Timer的cancel方法,拿到Timer的句柄后,我们可以在合适的时机对其进行cancel(多次调用cancel不会产生任何副作用,多余的cancel会被忽略)。

final timer = Timer.periodic(
const Duration(seconds: 1),
(timer) {
// TODO
},

final shouldStop = true;

test() {
if (shouldStop || timer.isActive) {
timer.cancel();
}
}

同时,Timer句柄还提供了isActive来判断当前Timer是否已经销毁,以及timer.tick来获取当前的计数值。

Timer意料之外

print('normal code start');
final zeroDurationTimer = Timer(
Duration.zero,
// Execute this callback ASAP but asynchronously
print('zeroDurationTimer callback');
},
print('normal code end');

我们来看上面的代码,执行结果如下。

normal code start
normal code end
zeroDurationTimer callback

这是因为所有的异步函数都被放到一个队列里进行调度,所以其回调的执行需要一点时间。因此,上面异步回调中的代码,会在最后执行。

❝ 上面的代码还有一个简化的写法——使用Timer.run构造函数。 ❞
final zeroDurationTimer = Timer.run(
// Execute this callback ASAP but asynchronously
},
❝ 多个Timer.run,或者说是Future,实际上也会按照异步的方式,按队列顺序依次执行。 ❞
批处理Channel

那么这个东西能干嘛呢——它可以帮我们批量处理一部分Microtask里面的操作,例如我们下面这个操作。

import 'package:flutter/material.dart';

import 'batch_method_channel.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
const MyApp({super.key});

@override
State createState() => _MyAppState();
}

class _MyAppState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Plugin example app')),
body: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) => TestWidget(index),
),
),
);
}
}

class TestWidget extends StatelessWidget {
final int index;

const TestWidget(
this.index, {
Key? key,
}) : super(key: key);

@override
Widget build(BuildContext context) {
batchChannel.invokeMethod('getPlatformVersion', {'index': index.toString()});
return GridTile(child: Text('data $index'));
}
}

在上面的代码中,我们模拟一个类似埋点的需求,在Widget build的时候,调用Channel传递一些数据到Native(这里使用的是Plugin Demo的工程进行改造的)。

如果我们使用普通的Channel来处理这个需求,那么每个Item build的时候都会调用一次Channel,这些Channel的调用会造成一定的性能损耗,所以我们需要对Channel进行批处理。

❝ 经过测试发现,Channel的性能损耗其实已经很低了,是否批处理带来的性能提升,只能在一些比较差的设备上才能有所体现。 ❞

这个批处理的需求,就可以使用Timer来实现,代码如下。

import 'dart:async';

import 'package:flutter/services.dart';

final BatchMethodChannel batchChannel = BatchMethodChannel();

class BatchMethodChannel {
static const MethodChannel channel = MethodChannel('xys_flutter_batch_channel');

Timer? _timer;

final List> _methods = [];

void invokeMethod(String method, [Map? arguments]) {
if (_timer == null || !_timer!.isActive) {
_methods.clear();
_timer = Timer(Duration.zero, () {
channel.invokeMethod(
'batch_channel_invoke',
_methods,
);
});
}
_methods.add({'method': method}..addAll(arguments ?? {}));
}
}

当Widget build时,调用invokeMethod操作,首次调用时,会创建一个Timer,并将真实的channel.invokeMethod作为异步任务延迟执行,根据前面的解释,这个Callback只有当主线程队列全部执行完成后才会执行,所以,当页面上有源源不断的Widget build时,invokeMethod一直被执行,非首次的执行,会将Method参数添加到List中,等所有Widget调用完成,Callback进行了处理,将前面List中的所有数据一次性通过channel.invokeMethod执行,从而形成了批处理的功能。

那么在Native侧收到批处理的消息后,就需要遍历List来处理每个Method,完成相应的操作。

when (call.method) {
"batch_channel_invoke" -> {
val callArguments: List> = call.arguments as List>
Log.d("xys", "batch_channel_invoke: $callArguments")
else -> {
result.notImplemented()

这种对Channel批处理的方式,也是有一些使用局限的。首先,由于批处理的Channel在Native侧执行的时候,不一定全部都是同步方法,所以,批处理Channel无法做到等一批数据处理好之后的统一返回。它最合适的场景还是类似上面这种「单向」的Channel调用场景。其次,Channel的解析过程会比普通方式更加复杂一点,需要看场景使用。

❝ 当然,Batch Channel也不一定只能是「单向」的,通过一些其它方式,它也可以做到向普通Channel那样的双向通信,例如,我们可以使用EventChannel来配合BatchChannel使用,这样在Native侧处理好批处理数据后,通过Stream返回给Flutter侧的监听者,从而实现双向通信。这些内容,我们后续再分析。 ❞

向大家推荐下我的网站 https://www.yuque.com/xuyisheng 点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问



本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

作者:徐宜生

更文不易,点个“三连”支持一下

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
印度首富之子大婚在即,婚前派对只有一个字:壕!

印度首富之子大婚在即,婚前派对只有一个字:壕!

新民周刊
2024-06-16 15:44:36
陈冰:欧盟拟对中国电动车加征关税 德国为何最先着急?

陈冰:欧盟拟对中国电动车加征关税 德国为何最先着急?

直新闻
2024-06-16 22:32:23
1.9亿,勇士已仁至义尽!金州不亏欠克莱,只是对不起卢尼

1.9亿,勇士已仁至义尽!金州不亏欠克莱,只是对不起卢尼

老王大话体育
2024-06-16 20:44:53
姜萍圆梦大学不止职教高考,江苏教育主管部门回应

姜萍圆梦大学不止职教高考,江苏教育主管部门回应

齐鲁壹点
2024-06-16 14:58:15
人民日报祝贺女排4连胜收官:1/4决赛对手为日本 袁心玥16分该赞

人民日报祝贺女排4连胜收官:1/4决赛对手为日本 袁心玥16分该赞

颜小白的篮球梦
2024-06-16 21:56:34
视频疯传!外媒:G7峰会上意总理向马克龙投去“死亡凝视”,两人“争执”曝光

视频疯传!外媒:G7峰会上意总理向马克龙投去“死亡凝视”,两人“争执”曝光

环球网资讯
2024-06-16 13:41:16
为什么今年中国经济这么差?

为什么今年中国经济这么差?

趣说世界哈
2024-06-16 07:50:23
22岁卡车司机,带45岁女人跑长途,两人最喜欢经过百里无人区

22岁卡车司机,带45岁女人跑长途,两人最喜欢经过百里无人区

牛城王小帅
2024-06-14 11:45:37
网友称医院也能看到露大腿的美女护士,大V无语:大家别幻想了!

网友称医院也能看到露大腿的美女护士,大V无语:大家别幻想了!

可达鸭面面观
2024-06-16 20:29:28
太突然了!山东菏泽曹县翰林府长达7分29秒视频,为何引发热搜?

太突然了!山东菏泽曹县翰林府长达7分29秒视频,为何引发热搜?

火山诗话
2024-06-16 16:42:18
医大教师因抢救患儿迟到被罚后续:举报者身份被扒,校方二次回应

医大教师因抢救患儿迟到被罚后续:举报者身份被扒,校方二次回应

洛洛女巫
2024-06-16 13:41:45
出线仅一周!国足塞翁失马,上上签诞生,4鱼腩同组,直通世界杯

出线仅一周!国足塞翁失马,上上签诞生,4鱼腩同组,直通世界杯

小马哥谈体育
2024-06-17 00:55:26
美国撤销半导体出口许可证8天后,华为一口气发布近20款新品

美国撤销半导体出口许可证8天后,华为一口气发布近20款新品

蜉蝣说
2024-06-16 23:38:30
江苏南京,王先生存了500万元,当月就获得了35万元的利息。3个月后,他又获得了67万元的利息

江苏南京,王先生存了500万元,当月就获得了35万元的利息。3个月后,他又获得了67万元的利息

别人都叫我阿腈
2024-06-16 07:15:02
A股:刚刚,证监会发声!2亿股民:融券和转融通就不应该存在!

A股:刚刚,证监会发声!2亿股民:融券和转融通就不应该存在!

兵哥闲聊
2024-06-16 22:32:43
过分!龚翔宇哭泣的原因找到了,被观众大喊滚下去,还被扔东西

过分!龚翔宇哭泣的原因找到了,被观众大喊滚下去,还被扔东西

邹维体育
2024-06-16 22:31:14
牵涉“女首富”案,又一位越共中央高层受处分

牵涉“女首富”案,又一位越共中央高层受处分

中国新闻周刊
2024-06-16 15:09:59
王思聪21岁新女友出手了,晒两人甜蜜合影,发声力挺王思聪!

王思聪21岁新女友出手了,晒两人甜蜜合影,发声力挺王思聪!

古希腊掌管月桂的神
2024-06-16 18:11:18
井喷!双色球24068期:爆发25注一等奖,分落12省,二等奖190注

井喷!双色球24068期:爆发25注一等奖,分落12省,二等奖190注

王晓爱体彩
2024-06-17 00:12:54
2-1逆转!FIFA第7拒爆冷,替补83分钟闪电绝杀,队史最菜10号诞生

2-1逆转!FIFA第7拒爆冷,替补83分钟闪电绝杀,队史最菜10号诞生

体坛纪录片
2024-06-16 22:58:18
2024-06-17 05:32:49
Android群英传
Android群英传
Android群英传
440文章数 921关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

冷藏货车违规乘人致8人窒息后遇难 河南叶县通报

头条要闻

冷藏货车违规乘人致8人窒息后遇难 河南叶县通报

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

售17.68万-21.68万元 极狐阿尔法S5正式上市

态度原创

手机
亲子
数码
本地
公开课

手机要闻

荣耀X60i入网:配置全面升级,能否满足你的所有期待?

亲子要闻

玩这个游戏的都是勇士

数码要闻

618前三周彩电市场量额双降 百英寸市场价格竞争激烈

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版