HarmonyOS 报错ValueSerialize: don't support clone arraybuffer has external allocated buffer?

1、从本地的asset中读取数据,然后返回到上层回调,在回调中对数据进行处理,具体逻辑如下:

onFrame: (frame: Uint8Array) => {
  // 获取自Unix纪元以来的纳秒,第一个参数true表示纳秒,false表示毫秒
  currentTimeMillis = systemDateTime.getTime(false)
  if (CheckEmptyUtils.isEmptyUint8Array(frame)) {
    Logger.error(TAG, "frame is empty")
    return
  }
  /**
   * debug版本时进行的计算
   */
  if (isDebugVersion) {
    // 数据打印
    // let dataContent = ""
    // for (let index = 0; index < 32; index++) {
    //   dataContent += StrUtils.to2DigitHex(frame[index]);
    // }
    // Logger.info(TAG, "frame头部" + dataContent.length + ":" + dataContent)
  }
  // 返回原始数据到上层进行渲染,拍照的时候,存储数据
  if (mIFrameDataCallback) {
    mIFrameDataCallback.onOrgData(mPreviewWidth, mIrDataHeight, mInfoDataHeight, mTempDataHeight, frame)
  }
  // 发现在使用本地数据的时候,必须要进行数据的拷贝转换
  if (this.frameData) {
    currentTimeMillis1 = systemDateTime.getTime(false)
    /**
     * 向Worker子线程发送消息
     * 数据统一在线程中处理,防止回调数据和渲染的数据由于时间差而不同步
     * 报错:[ecmascript] ValueSerialize: don't support clone arraybuffer has external allocated buffer,                     considering transfer it
     *      [ecmascript] ValueSerialize: serialize data is incomplete
     * 经过版本回退的对比测试,发现是手机升级到NEXT 0.0.26之后的一个bug,跟app的API版本无关
     */
    for (let index = 0; index < frame.length; index++) {
      this.frameData[index] = frame[index];
    }
    timeuse1 = systemDateTime.getTime(false) - currentTimeMillis1
    let dataContent = ""
    for (let index = 0; index < 32; index++) {
      dataContent += StrUtils.to2DigitHex(frame[index]);
    }
    dataContent += "\n"
    for (let index = 0; index < 32; index++) {
      dataContent += StrUtils.to2DigitHex(this.frameData[index]);
    }
    Logger.info(TAG, "frame frameData " + dataContent.length + ":" + dataContent)

  }

  if (this.bulkWorkerInstance) {
    currentTimeMillis2 = systemDateTime.getTime(false)
    this.bulkWorkerInstance.postMessage({
      'type': WorkerDataCode.DATA_DEAL,
      'frame': frame, // 这里使用frame则报错,使用this.frameData则是正常的
    });
    timeuse2 = systemDateTime.getTime(false) - currentTimeMillis2
  }
  timeuse = systemDateTime.getTime(false) - currentTimeMillis
  Logger.info(TAG, "total timeuse:" + timeuse + " convert:" + timeuse1 + " postMessage:" + timeuse2)
}

2、发现回调回来的数据 frame必须一对一的赋值到this.frameData中,然后向bulkWorkerInstance这个worker中传递数据,才能正常运行,否则报错

3、我打印了回调的frame和一对一赋值之后的this.frameData,发现里面的数据是一样的

阅读 527
1 个回答

因为frame这个参数是onFrame函数创建的,会存在缓冲区跨线程使用情况,该参数不支持跨线程使用,因此给其他线程使用时需要拷贝一份新的才可行。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进