Harmony线程(1)——概述
类型
类型
任务
主线程
执行UI绘制管理主线程的ArkTS引擎实例,使多个UIAbility组件能够运行在其之上管理其他线程的ArkTS引擎实例分发交互事件处理应用代码的回调,包括事件处理和生命周期管理接收TaskPool以及Worker线程发送的消息。
TaskPool Worker
执行耗时操作,支持设置调度优先级、负载均衡等功能,推荐使用
Worker
执行耗时操作,支持线程间通信
Harmony线程(3)——Taskpool
概述
为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能
实现流程
开发者在主线程封装任务抛给任务队列(创建TaskGroup并通过addTask()添加对应的任务)
系统选择合适的工作线程,进行任务的分发及执行(通过execute()执行任务组,并指定优先级)
工作线程将结果返回给主线程
实现任务
实现任务的函数需要使用装饰器@Concurrent标注,且仅支持在.ets文件中使用。
从API version 11开始,实现任务的函数需要使用类方法时,该类必须使用装饰器@Sendable装饰器标注,且仅支持在.ets文件中使用。
任务函数在TaskPool工作线程的执行耗时不能超过3分钟(不包含Promise和async/await异步调用的耗时,例如网络下载、文件读写等I/O任务的耗时),否则会被强制退出。
实现任务的函数入参需满足序列化支持的类型
mport { taskpool } from '@kit.ArkTS';@Concurrentfunction imageProcessing(dataSlice ...
Harmony线程(2)——Worker
相关概念
概念
说明
宿主进程
创建Worker的线程称为宿主线程(不一定是主线程,工作线程也支持创建Worker子线程)
Worker子线程(或Actor线程、工作线程)
Worker自身的线程
序列化机制
Worker通过序列化机制与宿主线程之间相互通信,完成命令及数据交互
每个Worker子线程与宿主线程拥有独立的实例,包含基础设施、对象、代码段等,因此每个Worker启动存在一定的内存开销,需要限制Worker的子线程数量
创建
手动
//build-profile.json5"buildOption": { "sourceOption": { "workers": [ "./src/main/ets/workers/worker.ets" ] }}
自动
{moduleName}目录下任意位置,点击鼠标右键 > New > Worker
使用
导入模块
宿主线程指定worker, ...
代码规范(3)——坏代码示例
类型
神秘命名
重复代码
过长函数
过长参数列表
全局数据: 全局数据的问题在于,从代码库的任何一个角落都可以修改它,而且没有任何机制可以探测出到底哪段代码做出了修改。一次又一次,全局数据造成了一些诡异的 BUG,而问题的根源却在遥远的别处。
可变数据: 对数据的修改经常导致出乎意料的结果和难以发现的 BUG。我在一处更新数据,却没有意识到软件中的另一处期望着完全不同的数据。
发散式变化: 模块经常因为不同的原因在不同的方向上发生变化。
散弹式修改: 每遇到某种变化,你都必须在许多不同的类内做出许多小修改。
依恋情结: 所谓模块化,就是力求将代码分出区域,最大化区域内部的交互、最小化跨区域的交互。但有时你会发现,一个函数跟另一个模块中的函数或者数据交流格外频繁,远胜于在自己所处模块内部的交流。
数据泥团: 你经常在很多地方看到相同的三四项数据:两个类中相同的字段、许多函数签名中相同的参数。
基本类型偏执: 很多程序员不愿意创建对自己的问题域有用的基本类型,如钱、坐标、范围等。
重复的 switch: 在不同的地方反复使用相同的 switch 逻辑。问题在于:每当你想增加一个选择分支时, ...
代码规范(2)——重构
何时
事不过三,三则重构
当我需要理解其工作原理时,对其进行重构才会有价值
重写比重构容易
重构的时机(1)——见机行事
大部分重构应该是不起眼的、见机行事的。重构不是与编程割裂的行为
预备性重构
重构的最佳时机就在添加新功能之前
帮助理解的重构
捡垃圾式重构
不想从眼下正要完成的任务上跑题太多,但我也不想把垃圾留在原地,给将来的修改增加麻烦
如果我发现的垃圾很容易重构,我会马上重构它;如果重构需要花一些精力,我可能会拿一张便笺纸把它记下来,完成当下的任务再回来重构它。
重构的时机(2)——长期重构
每当有人靠近“重构区”的代码,就把它朝想要改进的方向推动一点
每次小改动之后,整个系统仍然照常工作
重构方法
测试用例
重构之前,先保证一组可靠的测试用例(有自我检验的能力)
重构清单
函数
重构方法
说明
提炼
过长的函数,或者一段需要注释才能理解的代码,将其中一段代码提取到一个独立函数中,并让函数名称解释该函数的用途
内联
1. 内联函数:如果一个函数的名称和函数体一样清晰易懂,则去掉函数调用,在调用点直接使用函数体2.内联临时变量:如果一个 ...
代码规范(1)——编写
命名
别害怕长名称
命名方式要保持一致。使用与模块名一脉相承的短语、名词和动词给函数命名
函数
函数要么做什么事,要么回答什么事(分离指令与询问,询问指的是如if-else)
函数只做一件事,函数中的语句都要在同一抽象层级上
让代码拥有自顶向下的阅读顺序,让每个函数后面都跟着下一抽象层级的函数
「单一出口」规则,其实不是那么有用。保持代码清晰才是最关键的:如果「单一出口」能使这个函数更清楚易读,那么就使用单一出口;否则就不必这么做。(《重构2》)
//单一出口double getPayAmount() { double result; if (_isDead) result = deadAmount(); else { if (_isSeparated) result = separatedAmount(); else { if (_isRetired) result = retiredAmount(); else result = normalPayAmount(); ...
Harmony疑难杂症(2)——布局
版本号
DevEco Studio NEXT Release
Build #DS-233.14475.28.36.503900
Build Version: 5.0.3.900, built on October 8, 2024
Runtime version: 17.0.10+1-b1087.17 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 11.0
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 8
Registry:
idea.plugins.compatible.build=IC-233.14475.28
Non-Bundled Plugins:
com.griffin.jsontotypescriptclass (1.0.2)
问题
问题说明
解决方式
将子组件置于父组件左上角
.aligin(AlignMent.TopStart)属性
Grid高度自适应
动态计算高度,.height(Math.f ...
Harmony疑难杂症(1)——模拟器
版本号
DevEco Studio NEXT Release
Build #DS-233.14475.28.36.503900
Build Version: 5.0.3.900, built on October 8, 2024
Runtime version: 17.0.10+1-b1087.17 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 11.0
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 8
Registry:
idea.plugins.compatible.build=IC-233.14475.28
Non-Bundled Plugins:
com.griffin.jsontotypescriptclass (1.0.2)
问题
问题说明
解决方式
调试时上传唤起相机白屏
杀掉相机进程,再点开相机,最后返回再度唤起相机即可