文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客
开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客
开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客
开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储-CSDN博客
开源 Arkts 鸿蒙应用 开发(七)数据持久--sqlite关系数据库-CSDN博客
开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机-CSDN博客
开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端-CSDN博客
开源 Arkts 鸿蒙应用 开发(十)通讯--Http-CSDN博客
开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改-CSDN博客
开源 Arkts 鸿蒙应用 开发(十二)传感器的使用-CSDN博客
推荐链接:
开源 java android app 开发(一)开发环境的搭建-CSDN博客
开源 java android app 开发(二)工程文件结构-CSDN博客
开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客
开源 java android app 开发(四)GUI界面重要组件-CSDN博客
开源 java android app 开发(五)文件和数据库存储-CSDN博客
开源 java android app 开发(六)多媒体使用-CSDN博客
开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客
开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客
开源 java android app 开发(九)后台之线程和服务-CSDN博客
开源 java android app 开发(十)广播机制-CSDN博客
开源 java android app 开发(十一)调试、发布-CSDN博客
开源 java android app 开发(十二)封库.aar-CSDN博客
推荐链接:
开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客
开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客
开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客
开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客
开源 Arkts 鸿蒙应用 开发(十)通讯--Http数据传输-CSDN博客开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客
本章内容主要演示了如何使用任务池(taskpool)执行并发任务,以及如何在任务之间通过事件发射器(emitter)进行通信。
1.TaskPool简介
2.源码解析
3.所有源码
4.延时效果
一、TaskPool简介
TaskPool为应用程序提供多线程环境,降低资源消耗并提高系统性能。无需管理线程生命周期。
1.1 运作机制示意图
1.2 TaskPool注意事项
实现任务的函数需要使用@Concurrent装饰器标注
@Concurrent
function printArrayBuffer(buffer: ArrayBuffer) {
return buffer;
}
二、源码解析
主要演示了如何使用任务池(taskpool)执行并发任务,以及如何在任务之间通过事件发射器(emitter)进行通信。
2.1 实现@Concurrent方法
// 3. 并发任务函数(仅使用局部变量和参数)
@Concurrent
function task1Function(iterations: number): void {
// 使用局部变量存储中间结果
let step: number;
let calcResult: number;
let progress: number;
let result = 0;
// 1. 首先将复杂计算函数定义为模块级函数
for (step = 1; step <= iterations; step++) {
// 调用模块级函数进行计算
//calcResult = performComplexCalculation(step);
for (let i = 0; i < 100000; i++) {
result += Math.sin(step) * Math.cos(i);
}
progress = (step / iterations) * 100;
emitter.emit("progress_update", {
data: {
step,
totalSteps: iterations,
result: result,
progress
} as ProgressData
});
}
}
2.2 taskpool创建和运行
// 按钮2 - 启动任务2和任务3
async myClick2() {
if (this.task2Running || this.task3Running) return;
this.task2Running = true;
this.task3Running = true;
this.message = "启动任务2和任务3";
this.task2 = new taskpool.Task(task2Function);
this.task3 = new taskpool.Task(task3Function);
await taskpool.execute(this.task2);
await taskpool.execute(this.task3);
console.info("任务2和任务3已启动");
}
2.3 使用Emitter进行线程间通信
Emitter用于同一进程内相同线程或不同线程间的事件处理,事件异步执行。使用时需要先订阅一个事件,然后发布该事件,发布完成后Emitter会将已发布的事件分发给订阅者,订阅者就会执行该事件订阅时设置的回调方法。当不需要订阅该事件时应及时取消订阅释放Emitter资源。
任务3订阅消息
@Concurrent
function task3Function(): void {
console.info("任务3正在运行,等待接收消息");
emitter.on("task2_to_task3", (data) => {
console.info("任务3收到消息: " + JSON.stringify(data));
});
}
按钮3发送消息
// 按钮3 - 从任务2向任务3发送消息
myClick3() {
if (!this.task2Running || !this.task3Running) {
this.message = "请先启动任务2和任务3";
return;
}
emitter.emit("task2_to_task3", {
data: {
message: "这是来自任务2的消息",
timestamp: new Date().getTime()
}
});
this.message1 = "已从任务2向任务3发送消息";
}
任务1每次进行复杂运算后,将进度条的值通过Emitter发送给主线程
@Concurrent
function task1Function(iterations: number): void {
// 使用局部变量存储中间结果
let step: number;
let calcResult: number;
let progress: number;
let result = 0;
// 1. 首先将复杂计算函数定义为模块级函数
for (step = 1; step <= iterations; step++) {
// 调用模块级函数进行计算
//calcResult = performComplexCalculation(step);
for (let i = 0; i < 100000; i++) {
result += Math.sin(step) * Math.cos(i);
}
progress = (step / iterations) * 100;
emitter.emit("progress_update", {
data: {
step,
totalSteps: iterations,
result: result,
progress
} as ProgressData
});
}
}
三、所有代码,不要权限配置,只有一个文件Index.ets
3.1 主要功能模块
1) 并发任务执行 (complexCalculationTask)
这是一个计算密集型任务,模拟复杂计算过程
使用@Concurrent装饰器标记,表示可以在任务池中并发执行
计算过程中通过emitter.emit()发送进度更新事件
包含嵌套循环计算正弦和余弦值并累加结果
2.)任务间通信 (task2Function 和 task3Function)
两个简单的并发任务,演示任务间通信
任务3监听"task2_to_task3"事件
任务2通过按钮触发向任务3发送消息
3) UI组件 (Index组件)
显示计算进度和结果
3.2 源码Index.ets
// index.ets
import taskpool from '@ohos.taskpool';
import { BusinessError } from '@ohos.base';
import emitter from '@ohos.events.emitter';
interface ProgressEvent {
data: ProgressData;
}
// 2. 定义进度数据类型
interface ProgressData {
step: number;
totalSteps: number;
result: number;
progress: number;
}
// 3. 并发任务函数(仅使用局部变量和参数)
@Concurrent
function task1Function(iterations: number): void {
// 使用局部变量存储中间结果
let step: number;
let calcResult: number;
let progress: number;
let result = 0;
// 1. 首先将复杂计算函数定义为模块级函数
for (step = 1; step <= iterations; step++) {
// 调用模块级函数进行计算
//calcResult = performComplexCalculation(step);
for (let i = 0; i < 100000; i++) {
result += Math.sin(step) * Math.cos(i);
}
progress = (step / iterations) * 100;
emitter.emit("progress_update", {
data: {
step,
totalSteps: iterations,
result: result,
progress
} as ProgressData
});
}
}
@Concurrent
function task2Function(): void {
console.info("任务2正在运行");
// 任务2将在按下按钮3时向任务3发送消息
}
@Concurrent
function task3Function(): void {
console.info("任务3正在运行,等待接收消息");
emitter.on("task2_to_task3", (data) => {
console.info("任务3收到消息: " + JSON.stringify(data));
});
}
@Entry
@Component
struct Index {
@State message: string = "准备执行复杂计算";
@State message1: string = "准备执行复杂计算";
@State progress: number = 0;
@State currentStep: number = 0;
@State results: number[] = [];
private taskRunning: boolean = false;
private task2Running: boolean = false;
private task3Running: boolean = false;
private task2: taskpool.Task | null = null;
private task3: taskpool.Task | null = null;
aboutToDisappear() {
emitter.off("progress_update");
}
async task1() {
if (this.taskRunning) return;
this.taskRunning = true;
this.resetState();
emitter.on("progress_update", (eventData: ProgressEvent) => {
this.updateProgress(eventData.data);
});
try {
const task = new taskpool.Task(task1Function, 10);
await taskpool.execute(task);
this.message = "计算完成!";
} catch (error) {
this.handleError(error as BusinessError);
} finally {
this.cleanup();
}
}
private resetState(): void {
this.message = "计算进行中...";
this.progress = 0;
this.currentStep = 0;
this.results = [];
}
private updateProgress(data: ProgressData): void {
this.currentStep = data.step;
this.progress = data.progress;
this.results = [...this.results, data.result];
this.message = `计算进度: ${this.currentStep}/20`;
}
private handleError(error: BusinessError): void {
this.message = `计算错误: ${error.message}`;
console.error("Task failed:", error);
}
private cleanup(): void {
this.taskRunning = false;
emitter.off("progress_update");
}
// 按钮2 - 启动任务2和任务3
async myClick2() {
if (this.task2Running || this.task3Running) return;
this.task2Running = true;
this.task3Running = true;
this.message = "启动任务2和任务3";
this.task2 = new taskpool.Task(task2Function);
this.task3 = new taskpool.Task(task3Function);
await taskpool.execute(this.task2);
await taskpool.execute(this.task3);
console.info("任务2和任务3已启动");
}
// 按钮3 - 从任务2向任务3发送消息
myClick3() {
if (!this.task2Running || !this.task3Running) {
this.message = "请先启动任务2和任务3";
return;
}
emitter.emit("task2_to_task3", {
data: {
message: "这是来自任务2的消息",
timestamp: new Date().getTime()
}
});
this.message1 = "已从任务2向任务3发送消息";
}
build() {
Column() {
Text(this.message)
.fontSize(20)
.margin(10);
Progress({
value: this.progress,
total: 100,
style: ProgressStyle.Linear
})
.width('90%')
.height(30)
.margin(10);
this.buildResultDisplay()
Column() {
Text(this.message1)
.fontSize(20)
.margin(10);
Button('启动任务2 - 创建任务2和任务3')
.width('80%')
.height(60)
.margin(10)
.onClick(() => this.myClick2());
Button('启动任务3 - 发送数据')
.width('80%')
.height(60)
.margin(10)
.onClick(() => this.myClick3());
}
}
.width('100%')
.height('100%')
.padding(10)
}
@Builder
buildResultDisplay() {
Column() {
Text(`当前步骤: ${this.currentStep}/20`)
.fontSize(16)
.margin(5);
Text(`最新结果: ${this.results[this.results.length - 1]?.toFixed(4) || '无'}`)
.fontSize(16)
.margin(5);
Button('开始复杂计算')
.width('80%')
.height(60)
.margin(10)
.onClick(() => this.task1());
}
}
}
四、演示效果
手机效果图片
任务2、3启动打印和任务3收到事件后的打印