这篇直接验证一块 NativeBuffer 是否真的能被 CPU 写入和再次读取:分配 320 × 180 RGBA 缓冲区,Map 后写入固定字节模式,Unmap,再次 Map,最后释放。页面只显示 Native 层返回值和校验和。

真机结果

页面显示:缓冲区 320 × 180Map / Unmap 0 / 0、CPU 校验值 6048、再次 Map 返回 0。这些数据来自同一次真机运行。

准备

  • DevEco Studio,API 26 工程。
  • HUAWEI Mate 60 Pro 真机。
  • Native 文件:entry/src/main/cpp/native_buffer_sync.cpp
  • ArkTS 页面:entry/src/main/ets/features/graphics2d/NativeBufferSyncPage.ets

实施过程

1. 配置并分配缓冲区

OH_NativeBuffer_Config config = {
  320, 180, NATIVEBUFFER_PIXEL_FMT_RGBA_8888,
  NATIVEBUFFER_USAGE_CPU_READ | NATIVEBUFFER_USAGE_CPU_WRITE |
  NATIVEBUFFER_USAGE_HW_TEXTURE, 0
};
OH_NativeBuffer* buffer = OH_NativeBuffer_Alloc(&config);

同时声明 CPU 读写和硬件纹理用途,后续可以把同一块缓冲区交给图形管线。

2. Map 写入固定模式

void* address = nullptr;
int32_t mapStatus = OH_NativeBuffer_Map(buffer, &address);
if (mapStatus == 0 && address != nullptr) {
  auto* bytes = static_cast<uint8_t*>(address);
  for (int i = 0; i < 64; i++) {
    bytes[i] = static_cast<uint8_t>(i * 3);
  }
}

前 64 个字节写入 0、3、6… 的固定序列,便于在 Native 层计算确定性的校验和。

3. Unmap 后再次映射

int32_t unmapStatus = OH_NativeBuffer_Unmap(buffer);
int32_t remapStatus = OH_NativeBuffer_Map(buffer, &address);
if (remapStatus == 0) {
  OH_NativeBuffer_Unmap(buffer);
}

真机日志中 map=0 unmap=0 remap=0 checksum=6048,说明映射、解除映射和再次映射都返回成功。

4. 退出释放引用

int32_t releaseStatus = OH_NativeBuffer_Unreference(buffer);

退出页面时只减少本实验持有的引用,日志记录 BUFFER_RELEASE status=0

遇到的情况与处理

只看到分配成功,无法判断同步是否完成

把 Map、Unmap、再次 Map 和校验和分开显示。分配成功不等于 CPU 已经能读写,必须逐项核对返回码。

校验和每次不同

不要读取未初始化的整块内存。本实验先写入固定 64 字节模式,再计算校验和,结果稳定为 6048

缓冲区泄漏

NativeBuffer 使用引用计数,退出路径必须调用 OH_NativeBuffer_Unreference();页面重复进入时先释放旧实例再创建新实例。

真机 Hilog

BUFFER_LAB_ENTER size=320x180 format=RGBA_8888 permissionRequired=false
BUFFER_READY alloc=0 map=0 unmap=0 remap=0 checksum=6048
BUFFER_RELEASE status=0

验证结果

验证项真机结果
NativeBuffer 分配返回 0
CPU Map返回 0
Unmap返回 0
再次 Map返回 0
数据校验checksum = 6048
引用释放返回 0

至此,NativeBuffer 的 CPU 映射、写入、解除映射、再次映射和释放链路已经在 API 26 真机完成验证。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐