HarmonyOS 子线程共享@Sendable怎么用?

现在用子线程查询数据,要把原有得数据传递到TaskTool任务里面但是我的class已经使用了注解@Observed无法和@Sendable共存,并且class里面有一个枚举,枚举又无法使用@Sendable注解,导致根本无法使用TaskTool,请问有没有更好的办法解决这个序列化的问题?

阅读 411
1 个回答

@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}`);
      }
    }
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进