HarmonyOS 鸿蒙Next 子线程共享@Sendable怎么用
HarmonyOS 鸿蒙Next 子线程共享@Sendable怎么用
更多关于HarmonyOS 鸿蒙Next 子线程共享@Sendable怎么用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
@Sendable共享模块就单独用来处理ui线程和子线程数据,ui页面的数据单独用@Observed修饰。然后把枚举改为number来处理,做好映射。 这边有个用worker来实现ui和数据库之间的数据操作,可以看一下
Index.ets
import worker, { MessageEvents } from '@ohos.worker';
import { Student } from '../database/student';
const workerInstance = new worker.ThreadWorker("entry/ets/workers/Worker.ets");
let context = getContext()
let nameArr = ['jack','tom','anlay','jany','lili','Aaron','Ben','Brandon','Cody','Mason']
@Entry
@Component
struct Index {
@State list: Student[] = [];
aboutToAppear(): void {
workerInstance.postMessage({code:99,data:context});
workerInstance.onmessage = (e:MessageEvents):void=>{
if(e.data.code == 101){
this.list = e.data.data
}
}
}
build() {
Row() {
Column() {
Row(){
Button('建表')
.onClick(() => {
workerInstance.postMessage({code:1,data:context});
})
Button('插入数据')
.onClick(() => {
let student:Student = new Student()
let index = Math.ceil(Math.random()*10)%10
student.name = nameArr[index]
student.age = Math.ceil(Math.random()*100)%18
student.salary = 2000 + Math.ceil(Math.random()*10000)%10000
workerInstance.postMessage({code:2,data:student});
})
Button('查询数据')
.onClick(() => {
workerInstance.postMessage({code:3,data:{}});
})
}
.width('100%')
.margin({top:10})
.justifyContent(FlexAlign.SpaceAround)
ForEach(this.list, (item: Student, index: number) => {
ViewA({ student: item})
})
}
.height('100%')
.width('100%')
}
}
}
@Component
export struct ViewA {
student: Student = new Student();
build() {
Row(){
Text("姓名:"+this.student.name)
Text("年龄:"+this.student.age.toString())
Text("费用:"+this.student.salary.toString())
}.width('100%').margin({top : 10 }).justifyContent(FlexAlign.SpaceEvenly)
}
}
Worker.ets
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import Rdb from '../database/rdb'
import { Student } from '../database/student';
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
let rdbTest: Rdb;
workerPort.onmessage = async (e: MessageEvents) => {
console.log('testtag onmessage' + JSON.stringify(e))
if (e.data.code == 1) {
rdbTest.CreateTable(); //建表
} else if (e.data.code == 2) {
let student = e.data.data as Student
await rdbTest.InsertData(student.name, student.age, student.salary); //添加数据
//添加新数据收立马查询,然后同时主线程
let studentArr = await rdbTest.QueryDataArr();
//将处理结果返回主线程
workerPort.postMessage({code:101,data:studentArr})
} else if (e.data.code == 3) {
let studentArr = await rdbTest.QueryDataArr();
//将处理结果返回主线程
workerPort.postMessage({code:101,data:studentArr})
} else {
rdbTest = await new Rdb('Student.db', e.data.data) //创建数据库
}
console.log('testtag onmessage end')
}
workerPort.onmessageerror = (e: MessageEvents) => {
console.log('testtag onmessageerror' + e)
}
workerPort.onerror = (e: ErrorEvent) => {
}
Student.ets
export class Student {
id: number = 0
name: string = ''
age: number = 1
salary:number = 0
}
rdb.ets
import relationalStore from '@ohos.data.relationalStore';
import { BusinessError, Callback } from '@ohos.base';
import { ValuesBucket } from '@ohos.data.ValuesBucket';
import { Student } from './student';
export default class Rdb {
rdbStore?: relationalStore.RdbStore;
constructor(storeName: string, context: Context) {
// 数据库配置
const STORE_CONFIG: relationalStore.StoreConfig = {
name: storeName, securityLevel: relationalStore.SecurityLevel.S1,
};
// 获取数据库Store
relationalStore.getRdbStore(context, STORE_CONFIG, (err: BusinessError, rdbStore: relationalStore.RdbStore) => {
this.rdbStore = rdbStore;
if (err) {
console.error(`Get RdbStore failed, code is ${err.code},message is ${err.message}`);
return;
}
console.info(`Get ${storeName} RdbStore successfully.`);
})
}
CreateTable() {
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS STUDENT (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,AGE INTEGER,SALARY INTEGER)';
if (this.rdbStore) {
this.rdbStore.executeSql(SQL_CREATE_TABLE); console.info(`CreateTable successfully.`);
}
}
InsertData(name: string, age: number, salary: number) {
// 插入数据
const valueBucket: ValuesBucket = { 'NAME': name, 'AGE': age, 'SALARY': salary };
setTimeout(() => {
if (this.rdbStore) {
this.rdbStore.insert('STUDENT', valueBucket, (err, rowId) => {
if (err) {
console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`);
return;
}
console.info(`Succeeded in inserting data. rowId:${rowId}`);
})
}
}, 10)
}
async InsertAsync(name: string, age: number, salary: number) {
let start = Date.now(); const valueBucket:
ValuesBucket = { 'NAME': name, 'AGE': age, 'SALARY': salary };
/* while (Date.now() - start <1000) { continue; } console.log('延时结束');*/
if (this.rdbStore) {
await this.rdbStore.insert('STUDENT', valueBucket, (err, rowId) => {
if (err) {
console.error(`Failed to insert data. Code:${err.code}, message:${err.message}`);
return;
}
console.info(`Succeeded in inserting data. rowId:${rowId}`);
})
}
}
DeleteData() {
let predicates = new relationalStore.RdbPredicates("STUDENT"); predicates.equalTo("NAME", "Lisa");
if (this.rdbStore != undefined) {
(this.rdbStore as relationalStore.RdbStore).delete(predicates, (err, rows) => {
if (err) { console.error(`Delete failed, code is ${err.code},message is ${err.message}`);
return;
}
console.info(`Delete rows: ${rows}`);
})
}
}
queryData() {
let predicates = new relationalStore.RdbPredicates("STUDENT") .notEqualTo('name', 'li') .orderByAsc('age') .orderByAsc('salary')
if (this.rdbStore) {
this.rdbStore.query(predicates, ["ID", 'NAME', 'AGE', 'SALARY'], (err, resultSet) => {
if (err) {
console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
return;
}
console.info(`ResultSet column names: ${resultSet.columnNames}, row count: ${resultSet.rowCount}`);
if (resultSet.rowCount == -1) {
console.info("rowCount=-1")
}
// resultSet是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始。
while (resultSet.goToNextRow()) {
const id = resultSet.getLong(resultSet.getColumnIndex("ID"));
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));
console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
}
// 释放数据集的内存
resultSet.close();
})
}
}
querySyncData() {
let predicates = new relationalStore.RdbPredicates("STUDENT") .notEqualTo('name', 'li') .orderByAsc('age') .orderByAsc('salary')
try {
if (this.rdbStore) {
let resultSet = this.rdbStore.querySync(predicates, ["ID", 'NAME', 'AGE', 'SALARY']);
console.info(`ResultSet column names: ${resultSet.columnNames}, row count: ${resultSet.rowCount}`);
while (resultSet.goToNextRow()) {
const id = resultSet.getLong(resultSet.getColumnIndex("ID"));
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));
console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
}
// 释放数据集的内存
resultSet.close();
}
} catch (err) {
console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
return;
}
}
UpdateData(name: string, age: number, salary: number) {
const valueBucket: ValuesBucket = { 'NAME': name, 'AGE': age, 'SALARY': salary };
let predicates = new relationalStore.RdbPredicates("EMPLOYEE");
predicates.equalTo("NAME", "Lisa");
if (this.rdbStore != undefined) {
(this.rdbStore as relationalStore.RdbStore).update(valueBucket, predicates, relationalStore.ConflictResolution.ON_CONFLICT_REPLACE, (err, rows) => {
if (err) {
console.error(`Updated failed, code is ${err.code},message is ${err.message}`);
return;
}
console.info(`Updated row count: ${rows}`);
})
}
}
QueryData(callback: Callback<string>) {
// 配置谓词
let predicates = new relationalStore.RdbPredicates("STUDENT");
let jsonData: Array<ValuesBucket> = new Array<ValuesBucket>()
if (this.rdbStore) {
this.rdbStore.query(predicates, ["ID", 'NAME', 'AGE', 'SALARY'], (err, resultSet) => {
if (err) {
console.error(`Failed to query data. Code:${err.code}, message:${err.message}`);
return;
}
console.info(`ResultSet column names: ${resultSet.columnNames}, row count: ${resultSet.rowCount}`);
if (resultSet.rowCount == -1) {
console.info("rowCount=-1")
}
// resultSet是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始。
while (resultSet.goToNextRow()) {
const id = resultSet.getLong(resultSet.getColumnIndex("ID"));
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));
console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
const valueBucket: ValuesBucket = { 'ID': id, 'NAME': name, 'AGE': age, 'SALARY': salary};
jsonData.push(valueBucket)
}
// 释放数据集的内存
resultSet.close();
// console.info("JSON: " + JSON.stringify(jsonData)) callback(JSON.stringify(jsonData))
})
}
}
async QueryDataArr(): Promise<Student[]> {
// 配置谓词
let predicates = new relationalStore.RdbPredicates("STUDENT");
let rdbData: Array<Student> = new Array<Student>()
if (this.rdbStore) {
let resultSet = this.rdbStore.querySync(predicates, ["ID", 'NAME', 'AGE', 'SALARY'])
while (resultSet.goToNextRow()) {
const id = resultSet.getLong(resultSet.getColumnIndex("ID"));
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));
console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
const valueBucket: Student = new Student();
valueBucket.id = id
valueBucket.name = name
valueBucket.age = age
valueBucket.salary = salary
rdbData.push(valueBucket)
}
// 释放数据集的内存
resultSet.close();
// console.info("JSON: " + JSON.stringify(jsonData)) callback(JSON.stringify(jsonData))
}
return rdbData
}
queryKeySync() {
let predicates = new relationalStore.RdbPredicates("STUDENT");
predicates.equalTo("NAME", "Lisa");
if (this.rdbStore != undefined) {
try {
let resultSet: relationalStore.ResultSet = (this.rdbStore as relationalStore.RdbStore).querySync(predicates, ["ID", "NAME", "AGE", "SALARY"]);
console.info(`ResultSet column names: ${resultSet.columnNames}, column count: ${resultSet.columnCount}`);
// resultSet是一个数据集合的游标,默认指向第-1个记录,有效的数据从0开始。
while (resultSet.goToNextRow()) {
const id = resultSet.getLong(resultSet.getColumnIndex("ID"));
const name = resultSet.getString(resultSet.getColumnIndex("NAME"));
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"));
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"));
console.info(`id=${id}, name=${name}, age=${age}, salary=${salary}`);
}
// 释放数据集的内存
resultSet.close();
} catch (err) {
console.error(`Query failed, code is ${err.code},message is ${err.message}`);
}
}
}
}
更多关于HarmonyOS 鸿蒙Next 子线程共享@Sendable怎么用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙系统中,@Sendable
关键字主要用于确保闭包(Closure)或函数在并发环境中安全地传递和调用。在鸿蒙的多线程编程中,若想在子线程中安全地共享数据或调用函数,可以遵循以下使用方式:
@Sendable
通常与 @MainActor
、@Actor
等并发上下文标记一起使用,来明确闭包的并发安全性。但在鸿蒙系统中,具体的语法和标记可能有所不同,通常通过特定的API或框架来管理并发。
对于鸿蒙Next版本,如果你需要在子线程中共享数据,应使用鸿蒙提供的并发处理机制,如任务调度器(Task Dispatcher)或其他线程同步机制。@Sendable
闭包可以通过这些机制安全地在不同线程间传递。
示例代码片段(假设鸿蒙提供了类似Swift的语法支持,实际需参考鸿蒙API文档):
// 假设有一个函数需要在子线程中执行,并接收一个@Sendable闭包
func performInBackground(task: @escaping @Sendable () -> Void) {
// 鸿蒙的线程或任务调度代码
}
// 创建一个@Sendable闭包
let myTask: @Sendable () -> Void = {
// 执行任务
}
// 在子线程中执行
performInBackground(task: myTask)
如果问题依旧没法解决请联系官网客服, 官网地址是:https://www.itying.com/category-93-b0.html